use of io.nuls.kernel.utils.VarInt in project nuls by nuls-io.
the class ContractUtxoServiceImpl method saveUtxoForContractAddress.
/**
* 从地址的维度上讲,分为两大类交易
* 第一大类交易是普通地址转入合约地址
* 合约交易 - 调用合约时 调用者地址向合约地址转入金额
* 普通转账交易 - 普通地址向合约地址转入金额
* 第二大类交易是智能合约特殊转账交易,合约地址转出到普通地址/合约地址
*
* @param tx
* @return
*/
@Override
public Result saveUtxoForContractAddress(Transaction tx) {
if (tx == null) {
return Result.getFailed(KernelErrorCode.NULL_PARAMETER);
}
CoinData coinData = tx.getCoinData();
if (coinData != null) {
// 在合约独立账本中,只有合约转账(从合约转出)交易才能从合约地址中转出金额,所以只有这类交易才处理fromCoinData -> delete - from
List<byte[]> fromList = new ArrayList<>();
// 合约特殊转账交易
List<Coin> froms = new ArrayList<>();
List<Coin> deleteFroms = new ArrayList<>();
if (tx.getType() == ContractConstant.TX_TYPE_CONTRACT_TRANSFER) {
froms = coinData.getFrom();
byte[] fromSource;
byte[] utxoFromTxHash;
byte[] utxoFromIndex;
int txHashSize = tx.getHash().size();
Coin fromOfFromCoin;
for (Coin from : froms) {
fromSource = from.getOwner();
utxoFromTxHash = new byte[txHashSize];
utxoFromIndex = new byte[fromSource.length - txHashSize];
System.arraycopy(fromSource, 0, utxoFromTxHash, 0, txHashSize);
System.arraycopy(fromSource, txHashSize, utxoFromIndex, 0, utxoFromIndex.length);
fromOfFromCoin = from.getFrom();
if (fromOfFromCoin == null) {
Transaction sourceTx = null;
try {
sourceTx = ledgerService.getTx(NulsDigestData.fromDigestHex(Hex.encode(utxoFromTxHash)));
} catch (Exception e) {
throw new NulsRuntimeException(e);
}
if (sourceTx == null) {
return Result.getFailed(TransactionErrorCode.TX_NOT_EXIST);
}
fromOfFromCoin = sourceTx.getCoinData().getTo().get((int) new VarInt(utxoFromIndex, 0).value);
}
// 非合约地址在合约账本中不处理
if (!ContractUtil.isLegalContractAddress(fromOfFromCoin.getOwner())) {
continue;
}
from.setFrom(fromOfFromCoin);
from.setTempOwner(fromOfFromCoin.getOwner());
from.setKey(asString(fromSource));
deleteFroms.add(from);
fromList.add(fromSource);
}
}
// save utxo - to
List<Coin> tos = coinData.getTo();
List<Coin> contractTos = new ArrayList<>();
List<Entry<byte[], byte[]>> toList = new ArrayList<>();
byte[] txHashBytes;
try {
txHashBytes = tx.getHash().serialize();
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
Coin to;
byte[] toAddress;
byte[] outKey;
for (int i = 0, length = tos.size(); i < length; i++) {
to = tos.get(i);
// toAddress = to.getOwner();
// 非合约地址在合约账本中不处理
toAddress = to.getAddress();
if (!ContractUtil.isLegalContractAddress(toAddress)) {
continue;
}
try {
outKey = ArraysTool.concatenate(txHashBytes, new VarInt(i).encode());
to.setTempOwner(toAddress);
to.setKey(asString(outKey));
contractTos.add(to);
toList.add(new Entry<byte[], byte[]>(outKey, to.serialize()));
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
}
Result<List<Entry<byte[], byte[]>>> result = contractUtxoStorageService.batchSaveAndDeleteUTXO(toList, fromList);
if (result.isFailed() || result.getData() == null) {
return Result.getFailed();
}
// 刷新余额
contractBalanceManager.refreshBalance(contractTos, deleteFroms);
}
return Result.getSuccess();
}
use of io.nuls.kernel.utils.VarInt in project nuls by nuls-io.
the class ContractUtxoServiceImpl method deleteUtxoOfTransaction.
@Override
public Result deleteUtxoOfTransaction(Transaction tx) {
if (tx == null) {
return Result.getFailed(KernelErrorCode.NULL_PARAMETER);
}
CoinData coinData = tx.getCoinData();
byte[] txHashBytes;
try {
txHashBytes = tx.getHash().serialize();
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
if (coinData != null) {
// delete utxo - to
List<Coin> tos = coinData.getTo();
List<Coin> contractTos = new ArrayList<>();
List<byte[]> toList = new ArrayList<>();
byte[] outKey;
Coin to;
byte[] toAddress;
for (int i = 0, length = tos.size(); i < length; i++) {
to = tos.get(i);
// toAddress = to.();
toAddress = to.getAddress();
if (!ContractUtil.isLegalContractAddress(toAddress)) {
continue;
}
outKey = ArraysTool.concatenate(txHashBytes, new VarInt(i).encode());
to.setTempOwner(toAddress);
to.setKey(asString(outKey));
contractTos.add(to);
toList.add(outKey);
}
// save - from
List<Entry<byte[], byte[]>> fromList = new ArrayList<>();
List<Coin> froms = new ArrayList<>();
if (tx.getType() == ContractConstant.TX_TYPE_CONTRACT_TRANSFER) {
froms = coinData.getFrom();
int txHashSize = tx.getHash().size();
byte[] fromSource;
byte[] utxoFromHash;
byte[] utxoFromIndex;
Transaction sourceTx;
Coin sourceTxCoinTo;
for (Coin from : froms) {
fromSource = from.getOwner();
utxoFromHash = new byte[txHashSize];
utxoFromIndex = new byte[fromSource.length - txHashSize];
System.arraycopy(fromSource, 0, utxoFromHash, 0, txHashSize);
System.arraycopy(fromSource, txHashSize, utxoFromIndex, 0, utxoFromIndex.length);
try {
sourceTx = ledgerService.getTx(NulsDigestData.fromDigestHex(Hex.encode(utxoFromHash)));
} catch (Exception e) {
continue;
}
if (sourceTx == null) {
return Result.getFailed(TransactionErrorCode.TX_NOT_EXIST);
}
sourceTxCoinTo = sourceTx.getCoinData().getTo().get((int) new VarInt(utxoFromIndex, 0).value);
if (!ContractUtil.isLegalContractAddress(sourceTxCoinTo.getAddress())) {
continue;
}
from.setFrom(sourceTxCoinTo);
from.setTempOwner(sourceTxCoinTo.getAddress());
from.setKey(asString(fromSource));
try {
fromList.add(new Entry<byte[], byte[]>(fromSource, sourceTxCoinTo.serialize()));
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
}
}
// 函数将返回在数据库中存在的to
Result<List<Entry<byte[], byte[]>>> result = contractUtxoStorageService.batchSaveAndDeleteUTXO(fromList, toList);
if (result.isFailed() || result.getData() == null) {
return Result.getFailed();
}
// 回滚余额, 找到已删除的from 加回去, 筛选出已保存的to 减掉
contractBalanceManager.refreshBalance(froms, contractTos);
}
return Result.getSuccess();
}
use of io.nuls.kernel.utils.VarInt in project nuls by nuls-io.
the class ContractTxServiceImpl method saveUnConfirmedTokenTransfer.
private Result<byte[]> saveUnConfirmedTokenTransfer(CallContractTransaction tx, String sender, String contractAddress, String methodName, String[][] args) {
try {
byte[] senderBytes = AddressTool.getAddress(sender);
byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
ContractAddressInfoPo po = contractAddressInfoResult.getData();
if (po != null && po.isNrc20() && ContractUtil.isTransferMethod(methodName)) {
byte[] txHashBytes = tx.getHash().serialize();
byte[] infoKey = ArraysTool.concatenate(senderBytes, txHashBytes, new VarInt(0).encode());
ContractTokenTransferInfoPo tokenTransferInfoPo = new ContractTokenTransferInfoPo();
if (ContractConstant.NRC20_METHOD_TRANSFER.equals(methodName)) {
String to = args[0][0];
String tokenValue = args[1][0];
BigInteger token = new BigInteger(tokenValue);
Result result = contractBalanceManager.subtractContractToken(sender, contractAddress, token);
if (result.isFailed()) {
return result;
}
contractBalanceManager.addContractToken(to, contractAddress, token);
tokenTransferInfoPo.setFrom(senderBytes);
tokenTransferInfoPo.setTo(AddressTool.getAddress(to));
tokenTransferInfoPo.setValue(token);
} else {
String from = args[0][0];
// 转出的不是自己的代币(代币授权逻辑),则不保存token待确认交易,因为有调用合约的待确认交易
if (!sender.equals(from)) {
return Result.getSuccess();
}
String to = args[1][0];
String tokenValue = args[2][0];
BigInteger token = new BigInteger(tokenValue);
Result result = contractBalanceManager.subtractContractToken(from, contractAddress, token);
if (result.isFailed()) {
return result;
}
contractBalanceManager.addContractToken(to, contractAddress, token);
tokenTransferInfoPo.setFrom(AddressTool.getAddress(from));
tokenTransferInfoPo.setTo(AddressTool.getAddress(to));
tokenTransferInfoPo.setValue(token);
}
tokenTransferInfoPo.setName(po.getNrc20TokenName());
tokenTransferInfoPo.setSymbol(po.getNrc20TokenSymbol());
tokenTransferInfoPo.setDecimals(po.getDecimals());
tokenTransferInfoPo.setTime(tx.getTime());
tokenTransferInfoPo.setContractAddress(contractAddress);
tokenTransferInfoPo.setBlockHeight(tx.getBlockHeight());
tokenTransferInfoPo.setTxHash(txHashBytes);
tokenTransferInfoPo.setStatus((byte) 0);
Result result = contractTokenTransferStorageService.saveTokenTransferInfo(infoKey, tokenTransferInfoPo);
if (result.isFailed()) {
return result;
}
return Result.getSuccess().setData(infoKey);
}
return Result.getSuccess();
} catch (Exception e) {
Log.error(e);
Result result = Result.getFailed(ContractErrorCode.CONTRACT_TX_CREATE_ERROR);
result.setMsg(e.getMessage());
return result;
}
}
use of io.nuls.kernel.utils.VarInt in project nuls by nuls-io.
the class BlockHeaderStorageServiceImpl method removeBlockHerader.
private Result removeBlockHerader(byte[] hashBytes) {
if (null == hashBytes) {
return Result.getFailed(KernelErrorCode.NULL_PARAMETER);
}
BlockHeaderPo blockHeaderPo = getBlockHeaderPo(hashBytes);
if (null == blockHeaderPo) {
return Result.getSuccess();
}
dbService.delete(ProtocolStorageConstant.DB_NAME_BLOCK_HEADER_INDEX, new VarInt(blockHeaderPo.getHeight()).encode());
try {
dbService.put(ProtocolStorageConstant.DB_NAME_BLOCK_HEADER_INDEX, bestBlockKey, blockHeaderPo.getPreHash().serialize());
} catch (IOException e) {
Log.error(e);
}
return dbService.delete(ProtocolStorageConstant.DB_NAME_BLOCK_HEADER, hashBytes);
}
Aggregations