public void Test_InvalidMinter() { var tx = new TransactionReceipt(); var context = new InvocationContext(_mintCntrlAdd, _stateManager.LastApprovedSnapshot, tx); var contract = new NativeTokenContract(context); var keyPair = new EcdsaKeyPair("0x4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32" .HexToBytes().ToPrivateKey()); var address = keyPair.PublicKey.GetAddress(); // set the allowedSupply { var input = ContractEncoder.Encode(Lrc20Interface.MethodSetAllowedSupply, Money.Parse("10000")); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.NativeTokenContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.Ok, contract.SetAllowedSupply(Money.Parse("10000").ToUInt256(), frame)); } // mint tokens to address { var input = ContractEncoder.Encode(Lrc20Interface.MethodMint, address, Money.Parse("100").ToUInt256()); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.NativeTokenContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.ExecutionHalted, contract.Mint(address, Money.Parse("100").ToUInt256(), frame)); Assert.AreEqual(Money.Parse("0"), context.Snapshot.Balances.GetBalance(address)); } }
private byte[] ReadSystemContractData(UInt160 contractAddress, string method, params dynamic[] values) { var snapshot = _stateManager.LastApprovedSnapshot; var context = new InvocationContext(_nodeAddress, snapshot, new TransactionReceipt { Block = snapshot.Blocks.GetTotalBlockHeight(), }); var input = ContractEncoder.Encode(method, values); var call = _contractRegisterer.DecodeContract(context, contractAddress, input); if (call is null) { throw new Exception("System contract invocation failed"); } var result = VirtualMachine.InvokeSystemContract(call, context, input, 100_000_000); if (result.Status != ExecutionStatus.Ok) { throw new Exception("System contract failed"); } return(result.ReturnValue !); }
public ExecutionStatus Allowance(UInt160 owner, UInt160 spender, SystemContractExecutionFrame frame) { var allowance = GetAllowance(owner, spender); frame.ReturnValue = ContractEncoder.Encode(null, allowance); return(ExecutionStatus.Ok); }
public void Test_SetMinter() { var tx = new TransactionReceipt(); var context = new InvocationContext(_mintCntrlAdd, _stateManager.LastApprovedSnapshot, tx); var contract = new NativeTokenContract(context); // set the minter { var input = ContractEncoder.Encode(Lrc20Interface.MethodSetMinter, _minterAdd); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.NativeTokenContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.Ok, contract.SetMinter(_minterAdd, frame)); var decoder = new ContractDecoder(frame.ReturnValue); var res = decoder.Decode("uint160")[0] as UInt160 ?? throw new Exception("Invalid return value format"); Assert.AreEqual(_minterAdd, res); } // get the minter { var input = ContractEncoder.Encode(Lrc20Interface.MethodGetMinter); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.NativeTokenContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.Ok, contract.GetMinter(frame)); var decoder = new ContractDecoder(frame.ReturnValue); var res = decoder.Decode("uint160")[0] as UInt160 ?? throw new Exception("Invalid return value format"); Assert.AreEqual(_minterAdd, res); } }
public ExecutionStatus SetAllowedSupply(UInt256 amount, SystemContractExecutionFrame frame) { frame.UseGas(GasMetering.NativeTokenApproveCost); if (!frame.InvocationContext.Sender.Equals(_mintCntrlAdd)) { return(ExecutionStatus.ExecutionHalted); } var amountMoney = amount.ToMoney(); if (amountMoney > _maxSupply) { return(ExecutionStatus.ExecutionHalted); } if (amountMoney <= _context.Snapshot.Balances.GetSupply()) { return(ExecutionStatus.ExecutionHalted); } _context.Snapshot.Balances.SetAllowedSupply(amountMoney); frame.ReturnValue = ContractEncoder.Encode(null, _context.Snapshot.Balances.GetAllowedSupply()); return(ExecutionStatus.Ok); }
public ExecutionStatus Mint(UInt160 address, UInt256 amount, SystemContractExecutionFrame frame) { frame.UseGas(GasMetering.NativeTokenApproveCost); if (!frame.InvocationContext.Sender.Equals(_context.Snapshot.Balances.GetMinter())) { return(ExecutionStatus.ExecutionHalted); } var totalSupply = _context.Snapshot.Balances.GetSupply(); var amountMoney = amount.ToMoney(); if (totalSupply + amountMoney > _maxSupply || totalSupply + amountMoney > _context.Snapshot.Balances.GetAllowedSupply()) { return(ExecutionStatus.ExecutionHalted); } var newBalance = _context.Snapshot?.Balances.AddBalance(address, amountMoney, true); if (newBalance is null) { return(ExecutionStatus.ExecutionHalted); } Emit(Lrc20Interface.EventMinted, address, amount); frame.ReturnValue = ContractEncoder.Encode(null, newBalance); return(ExecutionStatus.Ok); }
public void Test_SignAndRecover() { var keyPair = new EcdsaKeyPair("0xD95D6DB65F3E2223703C5D8E205D98E3E6B470F067B0F94F6C6BF73D4301CE48" .HexToBytes().ToPrivateKey()); var signer = new TransactionSigner(); var abi = ContractEncoder.Encode("hello()"); var tx = new Transaction { To = ContractRegisterer.LatokenContract, Invocation = ByteString.CopyFrom(abi), From = keyPair.PublicKey.GetAddress(), GasPrice = 123123, /* TODO: "calculate gas limit for input size" */ GasLimit = GasMetering.DefaultBlockGasLimit, Nonce = 0, Value = new BigInteger(0).ToUInt256() }; // using old chain id var receipt = signer.Sign(tx, keyPair, false); Assert.AreEqual(receipt.Hash.ToHex(), receipt.FullHash(false).ToHex()); var publicKey = receipt.RecoverPublicKey(false); Assert.AreEqual(keyPair.PublicKey.ToHex(), publicKey.ToHex()); Assert.AreEqual(keyPair.PublicKey.GetAddress().ToHex(), publicKey.GetAddress().ToHex()); // using new chain id receipt = signer.Sign(tx, keyPair, true); Assert.AreEqual(receipt.Hash.ToHex(), receipt.FullHash(true).ToHex()); publicKey = receipt.RecoverPublicKey(true); Assert.AreEqual(keyPair.PublicKey.ToHex(), publicKey.ToHex()); Assert.AreEqual(keyPair.PublicKey.GetAddress().ToHex(), publicKey.GetAddress().ToHex()); }
private TransactionReceipt BuildSystemContractTxReceipt(ulong blockIndex, UInt160 contractAddress, string methodSignature) { var nonce = _stateManager.LastApprovedSnapshot.Transactions.GetTotalTransactionCount(UInt160Utils.Zero); var abi = ContractEncoder.Encode(methodSignature); var tx = new Transaction { To = contractAddress, Value = UInt256Utils.Zero, From = UInt160Utils.Zero, Nonce = nonce, GasPrice = 0, /* TODO: gas estimation */ GasLimit = 100000000, Invocation = ByteString.CopyFrom(abi), }; return(HardforkHeights.IsHardfork_9Active(blockIndex) ? new TransactionReceipt { Hash = tx.FullHash(SignatureUtils.ZeroNew, true), Status = TransactionStatus.Pool, Transaction = tx, Signature = SignatureUtils.ZeroNew, } : new TransactionReceipt { Hash = tx.FullHash(SignatureUtils.ZeroOld, false), Status = TransactionStatus.Pool, Transaction = tx, Signature = SignatureUtils.ZeroOld, }); }
/* * CallContract * contractHash, UInt160 * sender, string * methodSignature, string * method args according its signature */ public string CallContract(string[] arguments) { var contractHash = arguments[1].HexToUInt160(); var contract = _stateManager.LastApprovedSnapshot.Contracts.GetContractByHash(contractHash); if (contract is null) { return($"Unable to find contract by hash {contractHash.ToHex()}"); } var sender = arguments[2]; var methodSignature = arguments[3]; var abi = ContractEncoder.Encode(methodSignature, ContractEncoder.RestoreTypesFromStrings(arguments.Skip(4))); var result = _stateManager.SafeContext(() => { var snapshot = _stateManager.NewSnapshot(); var invocationResult = VirtualMachine.InvokeWasmContract(contract, new InvocationContext(sender.HexToUInt160(), snapshot, new TransactionReceipt { // TODO: correctly fill in these fields }), abi, GasMetering.DefaultBlockGasLimit ); _stateManager.Rollback(); return(invocationResult); }); return(result.ReturnValue?.ToHex() ?? "0x"); }
public ExecutionStatus Approve(UInt160 spender, UInt256 amount, SystemContractExecutionFrame frame) { frame.UseGas(GasMetering.NativeTokenApproveCost); SetAllowance(Sender(), spender, amount); Emit(Lrc20Interface.EventApproval, Sender(), spender, amount); frame.ReturnValue = ContractEncoder.Encode(null, 1.ToUInt256()); return(ExecutionStatus.Ok); }
public static InvocationResult CallSystemContract(SystemContractExecutionFrame currentFrame, UInt160 contractAddress, UInt160 sender, string methodSignature, params dynamic[] values) { var context = currentFrame.InvocationContext.NextContext(sender); var input = ContractEncoder.Encode(methodSignature, values); // TODO: pass correct gas amount return(ContractInvoker.Invoke(contractAddress, context, input, 100_000_000)); }
private TransactionReceipt MakeFinishCircleTxReceipt() { var res = BuildSystemContractTxReceipt(ContractRegisterer.GovernanceContract, GovernanceInterface.MethodFinishCycle); Assert.False(_eventData.ContainsKey(res.Hash)); _eventData.Add(res.Hash, ByteString.CopyFrom(ContractEncoder.Encode(GovernanceInterface.EventFinishCycle))); return(res); }
public ExecutionStatus TotalSupply(SystemContractExecutionFrame frame) { frame.UseGas(GasMetering.NativeTokenTotalSupplyCost); var supply = _context.Snapshot?.Balances.GetSupply(); if (supply is null) { return(ExecutionStatus.ExecutionHalted); } frame.ReturnValue = ContractEncoder.Encode(null, supply); return(ExecutionStatus.Ok); }
public ExecutionStatus BalanceOf(UInt160 address, SystemContractExecutionFrame frame) { frame.UseGas(GasMetering.NativeTokenBalanceOfCost); var balance = _context.Snapshot?.Balances.GetBalance(address); if (balance is null) { return(ExecutionStatus.ExecutionHalted); } frame.ReturnValue = ContractEncoder.Encode(null, balance); return(ExecutionStatus.Ok); }
public ExecutionStatus SetMinter(UInt160 minterAddress, SystemContractExecutionFrame frame) { Logger.LogInformation($"SetMinter, Sender {frame.InvocationContext.Sender.ToHex()}, minterController {_mintCntrlAdd.ToHex()}. minter {minterAddress.ToHex()}"); frame.UseGas(GasMetering.NativeTokenApproveCost); if (!frame.InvocationContext.Sender.Equals(_mintCntrlAdd)) { return(ExecutionStatus.ExecutionHalted); } _context.Snapshot.Balances.SetMinter(minterAddress); frame.ReturnValue = ContractEncoder.Encode(null, _context.Snapshot.Balances.GetMinter().ToUInt256()); return(ExecutionStatus.Ok); }
public void Test_OneNodeCycle() { var tx = new TransactionReceipt(); var keyPair = new EcdsaKeyPair("0xD95D6DB65F3E2223703C5D8E205D98E3E6B470F067B0F94F6C6BF73D4301CE48" .HexToBytes().ToPrivateKey()); byte[] publicKey = CryptoUtils.EncodeCompressed(keyPair.PublicKey); var sender = keyPair.PublicKey.GetAddress(); var context = new InvocationContext(sender, _stateManager.LastApprovedSnapshot, tx); var contract = new StakingContract(context); var stakeAmount = BigInteger.Pow(10, 21); // Set balance for the staker { context.Snapshot.Balances.SetBalance(sender, Money.Parse("1000")); Assert.AreEqual(Money.Parse("1000"), context.Snapshot.Balances.GetBalance(sender)); } // Become staker { var input = ContractEncoder.Encode(StakingInterface.MethodBecomeStaker, publicKey, stakeAmount.ToUInt256()); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.StakingContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.Ok, contract.BecomeStaker(publicKey, stakeAmount.ToUInt256(), frame)); } // Get stake { var input = ContractEncoder.Encode(StakingInterface.MethodGetStake, sender); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.StakingContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.Ok, contract.GetStake(sender, frame)); Assert.AreEqual(Money.Parse("1000"), frame.ReturnValue.ToUInt256().ToMoney()); } // Able to validator { var input = ContractEncoder.Encode(StakingInterface.MethodIsAbleToBeValidator, sender); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.StakingContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.Ok, contract.IsAbleToBeValidator(sender, frame)); //Assert.AreEqual(1, BitConverter.ToInt32(frame.ReturnValue, 0)); } }
public ExecutionStatus Transfer(UInt160 recipient, UInt256 value, SystemContractExecutionFrame frame) { frame.UseGas(GasMetering.NativeTokenTransferCost); var from = _context.Sender ?? throw new InvalidOperationException(); var result = _context.Snapshot.Balances.TransferBalance( from, recipient, value.ToMoney() ); Emit(Lrc20Interface.EventTransfer, from, recipient, value); frame.ReturnValue = ContractEncoder.Encode(null, (result ? 1 : 0).ToUInt256()); return(ExecutionStatus.Ok); }
private TransactionReceipt MakeDistributeCycleRewardsAndPenaltiesTxReceipt() { var res = BuildSystemContractTxReceipt(ContractRegisterer.GovernanceContract, GovernanceInterface.MethodDistributeCycleRewardsAndPenalties); Assert.False(_eventData.ContainsKey(res.Hash)); // TODO: remove hardcoded block reward with value from settings var totalReward = Money.Parse("5.0") * (int)StakingContract.CycleDuration; _eventData.Add(res.Hash, ByteString.CopyFrom(ContractEncoder.Encode( GovernanceInterface.EventDistributeCycleRewardsAndPenalties, totalReward))); return(res); }
public ExecutionStatus TransferFrom( UInt160 from, UInt160 recipient, UInt256 value, SystemContractExecutionFrame frame ) { frame.UseGas(GasMetering.NativeTokenTransferFromCost); if (!SubAllowance(from, Sender(), value, frame)) { return(ExecutionStatus.ExecutionHalted); } var result = _context.Snapshot.Balances.TransferBalance(from, recipient, value.ToMoney()); Emit(Lrc20Interface.EventTransfer, from, recipient, value); frame.ReturnValue = ContractEncoder.Encode(null, (result ? 1 : 0).ToUInt256()); return(ExecutionStatus.Ok); }
private TransactionReceipt ApproveTx(UInt160 to, UInt256 value, int nonceInc, bool useNewChainId) { var input = ContractEncoder.Encode(Lrc20Interface.MethodApprove, to, value); var tx = new Transaction { To = ContractRegisterer.LatokenContract, Invocation = ByteString.CopyFrom(input), From = _wallet.EcdsaKeyPair.PublicKey.GetAddress(), GasPrice = (ulong)Money.Parse("0.0000001").ToWei(), GasLimit = 10_000_000, Nonce = _transactionPool.GetNextNonceForAddress(_wallet.EcdsaKeyPair.PublicKey.GetAddress()) + (ulong)nonceInc, Value = UInt256Utils.Zero, }; return(Signer.Sign(tx, _wallet.EcdsaKeyPair, useNewChainId)); }
private Transaction BuildSystemContractTx(UInt160 contractAddress, string mehodSignature, params dynamic[] values) { var transactionRepository = _stateManager.CurrentSnapshot.Transactions; var from = UInt160Utils.Zero; var nonce = transactionRepository.GetTotalTransactionCount(from); var abi = ContractEncoder.Encode(mehodSignature, values); return(new Transaction { To = contractAddress, Value = UInt256Utils.Zero, From = UInt160Utils.Zero, Nonce = nonce, GasPrice = 0, GasLimit = 100000000, Invocation = ByteString.CopyFrom(abi), }); }
public Transaction TokenTransferTransaction(UInt160 contract, UInt160 from, UInt160 to, Money value) { var nonce = _transactionPool.GetNextNonceForAddress(from); var abi = ContractEncoder.Encode("transfer(address,uint256)", to, value.ToUInt256()); var tx = new Transaction { To = contract, Invocation = ByteString.CopyFrom(abi), From = from, GasPrice = _CalcEstimatedBlockFee(), /* TODO: "calculate gas limit for input size" */ GasLimit = GasMetering.DefaultBlockGasLimit, Nonce = nonce, Value = UInt256Utils.Zero }; return(tx); }
public void Test_InvalidMintController() { var tx = new TransactionReceipt(); var context = new InvocationContext(_mintCntrlAdd, _stateManager.LastApprovedSnapshot, tx); var contract = new NativeTokenContract(context); // set minter { var input = ContractEncoder.Encode(Lrc20Interface.MethodSetMinter, _minterAdd); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.NativeTokenContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.Ok, contract.SetMinter(_minterAdd, frame)); var decoder = new ContractDecoder(frame.ReturnValue); var res = decoder.Decode("uint160")[0] as UInt160 ?? throw new Exception("Invalid return value format"); Assert.AreEqual(_minterAdd, res); } // set the allowedSupply { context = new InvocationContext(_stateManager.LastApprovedSnapshot.Balances.GetMinter(), _stateManager.LastApprovedSnapshot, tx); contract = new NativeTokenContract(context); var input = ContractEncoder.Encode(Lrc20Interface.MethodSetAllowedSupply, Money.Parse("10000")); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.NativeTokenContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.ExecutionHalted, contract.SetAllowedSupply(Money.Parse("10000").ToUInt256(), frame)); } // verify allowedSupply { var input = ContractEncoder.Encode(Lrc20Interface.MethodGetAllowedSupply); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.NativeTokenContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.Ok, contract.GetAllowedSupply(frame)); var decoder = new ContractDecoder(frame.ReturnValue); var res = decoder.Decode("uint256")[0] as UInt256 ?? throw new Exception("Invalid return value format"); Assert.AreEqual(Money.Parse("0"), res.ToMoney()); } }
public Transaction InvokeTransaction(UInt160 from, UInt160 contract, Money value, string methodSignature, params dynamic[] values) { var nonce = _transactionPool.GetNextNonceForAddress(from); var abi = ContractEncoder.Encode(methodSignature, values); var tx = new Transaction { To = contract, Invocation = ByteString.CopyFrom(abi), From = from, GasPrice = (ulong)_stateManager.CurrentSnapshot.NetworkGasPrice, /* TODO: "calculate gas limit for input size" */ GasLimit = 100000000, Nonce = nonce, Value = value.ToUInt256() }; return(tx); }
private TransactionReceipt MakeNextValidatorsTxReceipt() { var sk = Crypto.GeneratePrivateKey(); var pk = Crypto.ComputePublicKey(sk, false); var tx = _transactionBuilder.InvokeTransactionWithGasPrice( _wallet.EcdsaKeyPair.PublicKey.GetAddress(), ContractRegisterer.GovernanceContract, Money.Zero, GovernanceInterface.MethodChangeValidators, 0, UInt256Utils.ToUInt256(GovernanceContract.GetCycleByBlockNumber(_stateManager.LastApprovedSnapshot.Blocks.GetTotalBlockHeight())), (pk) ); var res = Signer.Sign(tx, _wallet.EcdsaKeyPair, true); Assert.False(_eventData.ContainsKey(res.Hash)); _eventData.Add(res.Hash, ByteString.CopyFrom(ContractEncoder.Encode(GovernanceInterface.EventChangeValidators, (pk)))); return(res); }
public void Test_SetMinterInvalidMintCtlr() { var keyPair = new EcdsaKeyPair("0x4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32" .HexToBytes().ToPrivateKey()); var address = keyPair.PublicKey.GetAddress(); var tx = new TransactionReceipt(); var context = new InvocationContext(address, _stateManager.LastApprovedSnapshot, tx); var contract = new NativeTokenContract(context); // set the minter { var input = ContractEncoder.Encode(Lrc20Interface.MethodSetMinter, _minterAdd); var call = _contractRegisterer.DecodeContract(context, ContractRegisterer.NativeTokenContract, input); Assert.IsNotNull(call); var frame = new SystemContractExecutionFrame(call !, context, input, 100_000_000); Assert.AreEqual(ExecutionStatus.ExecutionHalted, contract.SetMinter(_minterAdd, frame)); } }
private TransactionReceipt MakeKeygenSendValuesTxReceipt() { var proposer = new BigInteger(0).ToUInt256(); var value = new Byte[0]; var tx = _transactionBuilder.InvokeTransactionWithGasPrice( _wallet.EcdsaKeyPair.PublicKey.GetAddress(), ContractRegisterer.GovernanceContract, Money.Zero, GovernanceInterface.MethodKeygenSendValue, 0, UInt256Utils.ToUInt256(GovernanceContract.GetCycleByBlockNumber(_stateManager.LastApprovedSnapshot.Blocks.GetTotalBlockHeight())), proposer, (value) ); var res = Signer.Sign(tx, _wallet.EcdsaKeyPair, true); Assert.False(_eventData.ContainsKey(res.Hash)); _eventData.Add(res.Hash, ByteString.CopyFrom(ContractEncoder.Encode(GovernanceInterface.EventKeygenSendValue, proposer, (value)))); return(res); }
private JObject SendContract(string contract, string methodSignature, string arguments, ulong gasLimit) { var ecdsaKeyPair = _privateWallet.GetWalletInstance()?.EcdsaKeyPair; if (ecdsaKeyPair == null) { throw new Exception("Wallet is locked"); } if (string.IsNullOrEmpty(methodSignature)) { throw new ArgumentException("Invalid method signature specified", nameof(methodSignature)); } var contractHash = contract.HexToUInt160(); var contractByHash = _stateManager.LastApprovedSnapshot.Contracts.GetContractByHash(contractHash); if (contractByHash is null) { throw new ArgumentException("Unable to resolve contract by hash (" + contract + ")", nameof(contract)); } var from = ecdsaKeyPair.PublicKey.GetAddress(); var tx = _transactionBuilder.InvokeTransaction( from, contractHash, Money.Zero, methodSignature, ContractEncoder.RestoreTypesFromStrings(arguments.Split(','))); var signedTx = _transactionSigner.Sign(tx, ecdsaKeyPair, HardforkHeights.IsHardfork_9Active(_stateManager.LastApprovedSnapshot.Blocks.GetTotalBlockHeight() + 1)); var error = _transactionPool.Add(signedTx); return(new JObject { ["status"] = signedTx.Status.ToString(), ["gasLimit"] = gasLimit, ["gasUsed"] = signedTx.GasUsed, ["ok"] = error == OperatingError.Ok, ["result"] = signedTx.Hash.ToHex() }); }
private TransactionReceipt MakeCommitTransaction() { var biVarPoly = BiVarSymmetricPolynomial.Random(0); var commitment = biVarPoly.Commit().ToBytes(); var row = new Byte[0]; var tx = _transactionBuilder.InvokeTransactionWithGasPrice( _wallet.EcdsaKeyPair.PublicKey.GetAddress(), ContractRegisterer.GovernanceContract, Money.Zero, GovernanceInterface.MethodKeygenCommit, 0, UInt256Utils.ToUInt256(GovernanceContract.GetCycleByBlockNumber(_stateManager.LastApprovedSnapshot.Blocks.GetTotalBlockHeight())), commitment, new byte[][] { row } ); var res = Signer.Sign(tx, _wallet.EcdsaKeyPair, true); Assert.False(_eventData.ContainsKey(res.Hash)); _eventData.Add(res.Hash, ByteString.CopyFrom(ContractEncoder.Encode(GovernanceInterface.EventKeygenCommit, commitment, new byte[][] { row }))); return(res); }
/* * SendContract * contractHash, UInt160 * methodSignature, string * method args according its signature */ public string SendContract(string[] arguments) { var contractHash = arguments[1].HexToUInt160(); var contract = _stateManager.LastApprovedSnapshot.Contracts.GetContractByHash(contractHash); if (contract is null) { return($"Unable to find contract by hash {contractHash.ToHex()}"); } var methodSignature = arguments[2]; // TODO: verify method exists and its signature is correct var tx = _transactionBuilder.InvokeTransaction( _keyPair.PublicKey.GetAddress(), contractHash, Money.Zero, methodSignature, ContractEncoder.RestoreTypesFromStrings(arguments.Skip(3))); var signedTx = _transactionSigner.Sign(tx, _keyPair, HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1)); var error = _transactionPool.Add(signedTx); return(error != OperatingError.Ok ? $"Error adding tx {signedTx.Hash.ToHex()} to pool: {error}" : signedTx.Hash.ToHex()); }