use of io.nuls.kernel.model.Na in project nuls by nuls-io.
the class CoinDataTool method getCoinData.
public static CoinDataResult getCoinData(byte[] address, Na amount, int size, Na price, List<Coin> coinList) {
if (null == price) {
throw new NulsRuntimeException(KernelErrorCode.PARAMETER_ERROR);
}
CoinDataResult coinDataResult = new CoinDataResult();
coinDataResult.setEnough(false);
if (coinList.isEmpty()) {
return coinDataResult;
}
List<Coin> coins = new ArrayList<>();
Na values = Na.ZERO;
// 累加到足够支付转出额与手续费
for (int i = 0; i < coinList.size(); i++) {
Coin coin = coinList.get(i);
coins.add(coin);
size += coin.size();
if (i == 127) {
size += 1;
}
// 每次累加一条未花费余额时,需要重新计算手续费
Na fee = TransactionFeeCalculator.getFee(size, price);
values = values.add(coin.getNa());
/**
* 判断是否是脚本验证UTXO
*/
int signType = coinDataResult.getSignType();
if (signType != 3) {
if ((signType & 0x01) == 0 && coin.getTempOwner().length == 23) {
coinDataResult.setSignType((byte) (signType | 0x01));
size += P2PHKSignature.SERIALIZE_LENGTH;
} else if ((signType & 0x02) == 0 && coin.getTempOwner().length != 23) {
coinDataResult.setSignType((byte) (signType | 0x02));
size += P2PHKSignature.SERIALIZE_LENGTH;
}
}
// 需要判断是否找零,如果有找零,则需要重新计算手续费
if (values.isGreaterThan(amount.add(fee))) {
Na change = values.subtract(amount.add(fee));
Coin changeCoin = new Coin();
if (address[2] == NulsContext.P2SH_ADDRESS_TYPE) {
changeCoin.setOwner(SignatureUtil.createOutputScript(address).getProgram());
} else {
changeCoin.setOwner(address);
}
changeCoin.setNa(change);
fee = TransactionFeeCalculator.getFee(size + changeCoin.size(), price);
if (values.isLessThan(amount.add(fee))) {
continue;
}
changeCoin.setNa(values.subtract(amount.add(fee)));
if (!changeCoin.getNa().equals(Na.ZERO)) {
coinDataResult.setChange(changeCoin);
}
}
coinDataResult.setFee(fee);
if (values.isGreaterOrEquals(amount.add(fee))) {
coinDataResult.setEnough(true);
coinDataResult.setCoinList(coins);
break;
}
}
return coinDataResult;
}
use of io.nuls.kernel.model.Na in project nuls by nuls-io.
the class CallContractTxValidator method validate.
@Override
public ValidateResult validate(CallContractTransaction tx) throws NulsException {
CallContractData txData = tx.getTxData();
Na transferNa = Na.valueOf(txData.getValue());
byte[] contractAddress = txData.getContractAddress();
byte[] sender = txData.getSender();
Set<String> addressSet = SignatureUtil.getAddressFromTX(tx);
if (!ContractLedgerUtil.isExistContractAddress(contractAddress)) {
Log.error("contract call error: The contract does not exist.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST);
}
if (!addressSet.contains(AddressTool.getStringAddressByBytes(sender))) {
Log.error("contract call error: The contract caller is not the transaction creator.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.TX_DATA_VALIDATION_ERROR);
}
Na contractReceivedNa = Na.ZERO;
for (Coin coin : tx.getCoinData().getTo()) {
byte[] owner = coin.getOwner();
if (owner.length > 23) {
owner = coin.getAddress();
}
// Keep the change maybe a very small coin
if (addressSet.contains(AddressTool.getStringAddressByBytes(owner))) {
// When the receiver sign this tx,Allow it transfer small coin
continue;
}
if (coin.getLockTime() != 0) {
Log.error("contract call error: The amount of the transfer cannot be locked(UTXO status error).");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.UTXO_STATUS_CHANGE);
}
if (!ArraysTool.arrayEquals(owner, contractAddress)) {
Log.error("contract call error: The receiver is not the contract address.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.TX_DATA_VALIDATION_ERROR);
} else {
contractReceivedNa = contractReceivedNa.add(coin.getNa());
}
if (coin.getNa().isLessThan(ProtocolConstant.MININUM_TRANSFER_AMOUNT)) {
Log.error("contract call error: The amount of the transfer is too small.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.TOO_SMALL_AMOUNT);
}
}
if (contractReceivedNa.isLessThan(transferNa)) {
Log.error("contract call error: Insufficient amount to transfer to the contract address.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.INVALID_AMOUNT);
}
Na realFee = tx.getCoinData().getFee();
Na fee = TransactionFeeCalculator.getTransferFee(tx.size()).add(Na.valueOf(LongUtils.mul(txData.getGasLimit(), txData.getPrice())));
if (realFee.isGreaterOrEquals(fee)) {
return ValidateResult.getSuccessResult();
} else {
Log.error("contract call error: The contract transaction fee is not right.");
return ValidateResult.getFailedResult(this.getClass().getName(), TransactionErrorCode.FEE_NOT_RIGHT);
}
}
use of io.nuls.kernel.model.Na in project nuls by nuls-io.
the class CreateContractTxValidator method validate.
@Override
public ValidateResult validate(CreateContractTransaction tx) throws NulsException {
CreateContractData txData = tx.getTxData();
byte[] sender = txData.getSender();
byte[] contractAddress = txData.getContractAddress();
if (!ContractUtil.isLegalContractAddress(contractAddress)) {
Log.error("contract create error: Illegal contract address.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), ContractErrorCode.ILLEGAL_CONTRACT_ADDRESS);
}
Set<String> addressSet = SignatureUtil.getAddressFromTX(tx);
if (!addressSet.contains(AddressTool.getStringAddressByBytes(sender))) {
Log.error("contract create error: The contract creater is not the transaction creator.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.TX_DATA_VALIDATION_ERROR);
}
Na realFee = tx.getCoinData().getFee();
Na fee = TransactionFeeCalculator.getTransferFee(tx.size()).add(Na.valueOf(LongUtils.mul(txData.getGasLimit(), txData.getPrice())));
if (realFee.isGreaterOrEquals(fee)) {
return ValidateResult.getSuccessResult();
} else {
Log.error("contract create error: The contract transaction fee is not right.");
return ValidateResult.getFailedResult(this.getClass().getName(), TransactionErrorCode.FEE_NOT_RIGHT);
}
}
use of io.nuls.kernel.model.Na in project nuls by nuls-io.
the class ContractBalance method minusTempUsable.
public void minusTempUsable(Na amount) {
Na realUsable = this.getRealUsable();
Na tempUsable = realUsable.minus(amount);
this.usableConsensusReward = Na.ZERO;
this.consensusRewardCoins.clear();
this.usable = tempUsable;
}
use of io.nuls.kernel.model.Na in project nuls by nuls-io.
the class CallContractProcessor method getContractCall.
private ContractCall getContractCall(String[] args) {
ContractCall call = null;
try {
call = new ContractCall();
call.setSender(args[1].trim());
call.setGasLimit(Long.valueOf(args[2].trim()));
call.setPrice(Long.valueOf(args[3].trim()));
call.setContractAddress(args[4].trim());
call.setMethodName(args[5].trim());
long naValue = 0L;
Na na = Na.parseNuls(args[6].trim());
if (na != null) {
naValue = na.getValue();
}
call.setValue(naValue);
if (args.length == 9) {
String argType = args[7].trim();
if (argType.equals("-d")) {
call.setMethodDesc(args[8].trim());
} else if (argType.equals("-r")) {
call.setRemark(args[8].trim());
} else {
return null;
}
} else if (args.length == 11) {
String argType0 = args[7].trim();
String argType1 = args[9].trim();
boolean isType0D = argType0.equals("-d");
boolean isType1D = argType1.equals("-d");
boolean isType0R = argType0.equals("-r");
boolean isType1R = argType1.equals("-r");
if ((isType0D && isType1D) || (isType0R && isType1R)) {
// 不能同时为-d或-r
return null;
}
if (isType0D) {
call.setMethodDesc(args[8].trim());
}
if (isType0R) {
call.setRemark(args[8].trim());
}
if (isType1D) {
call.setMethodDesc(args[10].trim());
}
if (isType1R) {
call.setRemark(args[10].trim());
}
}
return call;
} catch (Exception e) {
e.fillInStackTrace();
return null;
}
}
Aggregations