Esempio n. 1
0
        private void BecomeStaker(BigInteger stakeAmount)
        {
            Logger.LogInformation("BecomeStaker");
            var tx = _transactionBuilder.InvokeTransaction(
                _systemContractReader.NodeAddress(),
                ContractRegisterer.StakingContract,
                Money.Zero,
                StakingInterface.MethodBecomeStaker,
                _systemContractReader.NodePublicKey(),
                (object)stakeAmount.ToUInt256()
                );

            AddTxToPool(tx);
        }
Esempio n. 2
0
        public JObject GetStakeTransaction(JObject opts)
        {
            var staker = opts["stakerAddress"]?.ToString().HexToBytes().ToUInt160() ??
                         throw new Exception($"\"stakerAddress\" {opts["stakerAddress"]} is not valid");

            var validatorPubKey = opts["validatorPublicKey"]?.ToString().HexToBytes() ??
                                  throw new Exception($"\"validatorPublicKey\" {opts["validatorPublicKey"]} is not valid");

            var stakeAmount = Money.Parse(opts["stakeAmount"]?.ToString() ??
                                          throw new Exception($"\"stakeAmount\" {opts["stakeAmount"]} is not valid")
                                          );
            var tx = _transactionBuilder.InvokeTransaction(
                staker,
                ContractRegisterer.StakingContract,
                Money.Zero,
                StakingInterface.MethodBecomeStaker,
                validatorPubKey,
                (object)stakeAmount.ToUInt256()
                );

            return(Web3DataFormatUtils.Web3UnsignedTransaction(tx, true));
        }
Esempio n. 3
0
        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()
            });
        }
Esempio n. 4
0
        /*
         * 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());
        }
Esempio n. 5
0
        private void TestContractDeployAndInvoke(int blockNum)
        {
            var keyPair = _wallet.EcdsaKeyPair;

            GenerateBlock(blockNum);
            blockNum++;
            // Deploy contract
            var byteCode = ByteCodeHex.HexToBytes();

            Assert.That(VirtualMachine.VerifyContract(byteCode, true), "Unable to validate smart-contract code");
            var from         = keyPair.PublicKey.GetAddress();
            var nonce        = _stateManager.LastApprovedSnapshot.Transactions.GetTotalTransactionCount(from);
            var contractHash = from.ToBytes().Concat(nonce.ToBytes()).Ripemd();
            var tx           = _transactionBuilder.DeployTransaction(from, byteCode);
            var signedTx     = Signer.Sign(tx, keyPair, HardforkHeights.IsHardfork_9Active((ulong)blockNum));
            var error        = _transactionPool.Add(signedTx);

            Assert.That(error == OperatingError.Ok, $"Can't add deploy tx to pool: {error}");
            GenerateBlock(blockNum);
            blockNum++;
            // check contract is deployed
            var contract = _stateManager.LastApprovedSnapshot.Contracts.GetContractByHash(contractHash);

            Assert.That(contract != null, "Failed to find deployed contract");

            // invoke deployed contract without blockchain
            var abi = ContractEncoder.Encode("test()");
            var transactionReceipt = new TransactionReceipt {
                Block = _stateManager.LastApprovedSnapshot.Blocks.GetTotalBlockHeight(),
            };

            transactionReceipt.Transaction       = new Transaction();
            transactionReceipt.Transaction.Value = 0.ToUInt256();
            var invocationResult = VirtualMachine.InvokeWasmContract(
                contract !,
                new InvocationContext(from, _stateManager.LastApprovedSnapshot, transactionReceipt),
                abi,
                GasMetering.DefaultBlockGasLimit
                );

            Assert.That(invocationResult.Status == ExecutionStatus.Ok, $"Failed to invoke deployed contract: {invocationResult.Status}");
            Assert.That(invocationResult.GasUsed > 0, "No gas used during contract invocation");
            Assert.That(invocationResult.ReturnValue !.ToHex() == "0x000000000000000000000000000000000000000000000000000000000000002a", "Invalid invocation return value");

            // invoke contract in blockchain
            var txInvoke = _transactionBuilder.InvokeTransaction(
                keyPair.PublicKey.GetAddress(),
                contractHash,
                Money.Zero,
                "test()",
                new dynamic[0]);
            var signedTxInvoke = Signer.Sign(txInvoke, keyPair, HardforkHeights.IsHardfork_9Active((ulong)blockNum));

            error = _transactionPool.Add(signedTxInvoke);
            Assert.That(error == OperatingError.Ok, $"Failed to add invoke tx to pool: {error}");
            GenerateBlock(blockNum);
            blockNum++;
            var tx2 =
                _stateManager.CurrentSnapshot.Transactions.GetTransactionByHash(signedTxInvoke.Hash);

            Assert.That(tx2 != null, "Failed to add invoke tx to block");
            Assert.That(tx2 !.Status == TransactionStatus.Executed, $"Failed to execute invoke tx: {tx2!.Status}");
            Assert.That(tx2.GasUsed > 0, "Invoke tx didn't use gas");
            // Invocation result is not stored in TransactionReceipt now, can't verify it
        }