/* * 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"); }
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() }); }
/* * 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()); }