use of io.nuls.kernel.model.Coin 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.Coin in project nuls by nuls-io.
the class BalanceManager method getCoinListByAddress.
public List<Coin> getCoinListByAddress(byte[] address) {
List<Coin> coinList = new ArrayList<>();
Collection<Entry<byte[], byte[]>> rawList = localUtxoStorageService.loadAllCoinList();
for (Entry<byte[], byte[]> coinEntry : rawList) {
Coin coin = new Coin();
try {
coin.parse(coinEntry.getValue(), 0);
} catch (NulsException e) {
Log.info("parse coin form db error");
continue;
}
if (Arrays.equals(coin.getAddress(), address)) {
coin.setTempOwner(coin.getOwner());
coin.setOwner(coinEntry.getKey());
coinList.add(coin);
}
}
return coinList;
}
use of io.nuls.kernel.model.Coin 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.Coin in project nuls by nuls-io.
the class ContractAcceptTransferredTxValidator method validate.
@Override
public ValidateResult validate(Transaction tx) throws NulsException {
if (tx.getCoinData() == null) {
return ValidateResult.getSuccessResult();
}
List<Coin> toList = tx.getCoinData().getTo();
if (toList == null || toList.size() == 0) {
return ValidateResult.getSuccessResult();
}
int type = tx.getType();
for (Coin coin : toList) {
if (ContractUtil.isLegalContractAddress(coin.getOwner())) {
if (type != NulsConstant.TX_TYPE_COINBASE && type != ContractConstant.TX_TYPE_CALL_CONTRACT) {
Log.error("contract data error: The contract does not accept transfers of this type[{}] of transaction.", type);
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.TX_DATA_VALIDATION_ERROR);
}
}
}
return ValidateResult.getSuccessResult();
}
use of io.nuls.kernel.model.Coin in project nuls by nuls-io.
the class ContractBalanceManager method handleLockedBalances.
private void handleLockedBalances(ContractBalance balance, Long blockHeight) {
balance.setLocked(Na.ZERO);
balance.setUsableConsensusReward(Na.ZERO);
Collection<Coin> lockedCoins = balance.getConsensusRewardCoins().values();
List<Coin> list = new ArrayList<>(lockedCoins);
Coin coin;
int size = list.size();
for (int i = 0; i < size; i++) {
coin = list.get(i);
if (coin.usable(blockHeight)) {
balance.addUsableConsensusReward(coin.getNa());
} else {
balance.addLocked(coin.getNa());
}
}
}
Aggregations