public async Task ReturnRemainingContractBalanceUponDelete()
    {
        // Setup the Simple Event Emitting Contract and An account for "send to".
        await using var fxAccount = await TestAccount.CreateAsync(_network);

        await using var fxContract = await EventEmittingContract.CreateAsync(_network);

        // Get the Info for the Account to receive funds before any changes happen.
        var infoBefore = await fxAccount.Client.GetAccountInfoAsync(fxAccount.Record.Address);

        Assert.Equal(fxAccount.CreateParams.InitialBalance, infoBefore.Balance);

        // Double check the balance on the contract, confirm it has hbars
        var contractBalanceBefore = await fxContract.Client.CallContractWithRecordAsync(new CallContractParams
        {
            Contract     = fxContract.ContractRecord.Contract,
            Gas          = 30000,
            FunctionName = "get_balance"
        });

        Assert.NotNull(contractBalanceBefore);
        Assert.InRange(fxContract.ContractParams.InitialBalance, 1, int.MaxValue);
        Assert.Equal(fxContract.ContractParams.InitialBalance, contractBalanceBefore.CallResult.Result.As <long>());

        // Delete the Contract, returning contract balance to Account
        var deleteContractRecord = await fxContract.Client.DeleteContractAsync(fxContract.ContractRecord.Contract, fxAccount.Record.Address, fxContract.PrivateKey);

        Assert.Equal(ResponseCode.Success, deleteContractRecord.Status);

        // Check the balance of account to see if it went up by contract's balance.
        var infoAfter = await fxAccount.Client.GetAccountInfoAsync(fxAccount.Record.Address);

        Assert.Equal(infoBefore.Balance + (ulong)fxContract.ContractParams.InitialBalance, infoAfter.Balance);
    }
        public async Task CanGetEventEmittingContractBytecode()
        {
            await using var fx = await EventEmittingContract.CreateAsync(_network);

            var bytecode = await fx.Client.GetContractBytecodeAsync(fx.ContractRecord.Contract);

            Assert.False(bytecode.IsEmpty);
        }
        public async Task CanGetContractBalanceFromCall()
        {
            await using var fx = await EventEmittingContract.CreateAsync(_network);

            var record = await fx.Client.CallContractWithRecordAsync(new CallContractParams
            {
                Contract     = fx.ContractRecord.Contract,
                Gas          = 300_000,
                FunctionName = "get_balance"
            });
示例#4
0
    public async Task CanCallContractMethodSendingFunds()
    {
        await using var fx = await EventEmittingContract.CreateAsync(_network);

        await using var fx2 = await TestAccount.CreateAsync(_network);

        var infoBefore = await fx2.Client.GetAccountInfoAsync(fx2.Record.Address);

        var record = await fx.Client.CallContractWithRecordAsync(new CallContractParams
        {
            Contract     = fx.ContractRecord.Contract,
            Gas          = 40000,
            FunctionName = "send_to",
            FunctionArgs = new[] { fx2.Record.Address }
        });

        Assert.NotNull(record);
        Assert.Equal(ResponseCode.Success, record.Status);
        Assert.False(record.Hash.IsEmpty);
        Assert.NotNull(record.Concensus);
        Assert.Empty(record.Memo);
        Assert.InRange(record.Fee, 0UL, ulong.MaxValue);
        Assert.Empty(record.CallResult.Error);
        Assert.False(record.CallResult.Bloom.IsEmpty);
        Assert.InRange(record.CallResult.Gas, 0UL, 300_000UL);
        Assert.Single(record.CallResult.Events);
        Assert.Empty(record.CallResult.CreatedContracts);

        // Now check the emitted Event
        var result = record.CallResult.Events[0];

        Assert.Equal(fx.ContractRecord.Contract, result.Contract);
        Assert.False(result.Bloom.IsEmpty);
        Assert.Single(result.Topic);
        Assert.Equal("9277a4302be4a765ae8585e09a9306bd55da10e20e59ed4f611a04ba606fece8", Hex.FromBytes(result.Topic[0]));

        Assert.Empty(record.CallResult.CreatedContracts);

        var(address, amount) = result.Data.As <Address, long>();
        Assert.Equal(fx2.Record.Address, address);
        Assert.Equal(fx.ContractParams.InitialBalance, amount);

        // Alternate Way
        var objects = result.Data.GetAll(typeof(Address), typeof(long));

        Assert.Equal(fx2.Record.Address, objects[0]);
        Assert.Equal(fx.ContractParams.InitialBalance, objects[1]);

        var infoAfter = await fx2.Client.GetAccountInfoAsync(fx2.Record.Address);

        Assert.Equal((ulong)fx.ContractParams.InitialBalance, infoAfter.Balance - infoBefore.Balance);
    }
示例#5
0
    public static async Task <EventEmittingContract> CreateAsync(NetworkCredentials networkCredentials, Action <EventEmittingContract> customize = null)
    {
        var fx = new EventEmittingContract();

        networkCredentials.Output?.WriteLine("STARTING SETUP: Event Emit Contract Create Configuration");
        (fx.PublicKey, fx.PrivateKey) = Generator.KeyPair();
        fx.Network    = networkCredentials;
        fx.FileParams = new CreateFileParams
        {
            Expiration   = DateTime.UtcNow.AddSeconds(7890000),//Generator.TruncatedFutureDate(12, 24),
            Endorsements = new Endorsement[] { networkCredentials.PublicKey },
            Contents     = Encoding.UTF8.GetBytes(EVENTEMIT_CONTRACT_BYTECODE)
        };
        fx.Client     = networkCredentials.NewClient();
        fx.FileRecord = await fx.Client.RetryKnownNetworkIssues(async client =>
        {
            return(await fx.Client.CreateFileWithRecordAsync(fx.FileParams, ctx =>
            {
                ctx.Memo = "Event Emit Contract Create: Uploading Contract File " + Generator.Code(10);
            }));
        });

        Assert.Equal(ResponseCode.Success, fx.FileRecord.Status);
        fx.ContractParams = new CreateContractParams
        {
            File           = fx.FileRecord.File,
            Administrator  = fx.PublicKey,
            Signatory      = fx.PrivateKey,
            Gas            = 300000,
            InitialBalance = 1_000_000,
            RenewPeriod    = TimeSpan.FromSeconds(7890000),//TimeSpan.FromDays(Generator.Integer(2, 4))
        };
        customize?.Invoke(fx);
        fx.ContractRecord = await fx.Client.RetryKnownNetworkIssues(async client =>
        {
            return(await fx.Client.CreateContractWithRecordAsync(fx.ContractParams, ctx =>
            {
                ctx.Memo = "Event Emit Contract Create: Instantiating Event Emit Instance " + Generator.Code(10);
            }));
        });

        Assert.Equal(ResponseCode.Success, fx.FileRecord.Status);
        fx.Network.Output?.WriteLine("SETUP COMPLETED: Event Emit Contract Instance Created");
        return(fx);
    }
示例#6
0
        public async Task CanGetContractBalanceFromLocalCall()
        {
            await using var fx = await EventEmittingContract.CreateAsync(_network);

            var result = await fx.Client.QueryContractAsync(new QueryContractParams
            {
                Contract     = fx.ContractRecord.Contract,
                Gas          = await _network.TinybarsFromGas(400),
                FunctionName = "get_balance"
            });

            Assert.NotNull(result);
            Assert.Empty(result.Error);
            Assert.True(result.Bloom.IsEmpty);
            Assert.InRange(result.Gas, 0UL, 400UL);
            Assert.Empty(result.Events);
            Assert.Equal(fx.ContractParams.InitialBalance, result.Result.As <long>());
        }
示例#7
0
        public async Task ReturnRemainingContractBalanceUponDelete()
        {
            // Setup the Simple Event Emitting Contract and An account for "send to".
            await using var fxAccount = await TestAccount.CreateAsync(_network);

            await using var fxContract = await EventEmittingContract.CreateAsync(_network);

            // Get the Info for the Account to receive funds before any changes happen.
            var infoBefore = await fxAccount.Client.GetAccountInfoAsync(fxAccount.Record.Address);

            Assert.Equal(fxAccount.CreateParams.InitialBalance, infoBefore.Balance);

            // Double check the balance on the contract, confirm it has hbars
            var contractBalanceBefore = await fxContract.Client.CallContractWithRecordAsync(new CallContractParams
            {
                Contract     = fxContract.ContractRecord.Contract,
                Gas          = 300_000,
                FunctionName = "get_balance"
            });
示例#8
0
        public async Task CanGetContractBalanceFromCall()
        {
            await using var fx = await EventEmittingContract.CreateAsync(_network);

            var record = await fx.Client.CallContractWithRecordAsync(new CallContractParams
            {
                Contract     = fx.ContractRecord.Contract,
                Gas          = await _network.TinybarsFromGas(400),
                FunctionName = "get_balance"
            });

            Assert.NotNull(record);
            Assert.Equal(ResponseCode.Success, record.Status);
            Assert.False(record.Hash.IsEmpty);
            Assert.NotNull(record.Concensus);
            Assert.Empty(record.Memo);
            Assert.InRange(record.Fee, 0UL, ulong.MaxValue);
            Assert.Empty(record.CallResult.Error);
            Assert.True(record.CallResult.Bloom.IsEmpty);
            Assert.InRange(record.CallResult.Gas, 0UL, 30_000UL);
            Assert.Empty(record.CallResult.Events);
            Assert.Equal(fx.ContractParams.InitialBalance, record.CallResult.Result.As <long>());
        }
示例#9
0
    public async Task AttemptToSendHbarsToDeletedAccountFails()
    {
        // Setup the Simple Event Emitting Contract and An account for "send to".
        await using var fxAccount1 = await TestAccount.CreateAsync(_network);

        await using var fxAccount2 = await TestAccount.CreateAsync(_network);

        await using var fxContract = await EventEmittingContract.CreateAsync(_network);

        // Get the Info for the account state and then delete the account.
        var info1Before = await fxAccount1.Client.GetAccountInfoAsync(fxAccount1.Record.Address);

        var info2Before = await fxAccount2.Client.GetAccountInfoAsync(fxAccount2.Record.Address);

        var delete1Receipt = await fxAccount1.Client.DeleteAccountAsync(fxAccount1.Record.Address, fxAccount1.Network.Payer, fxAccount1.PrivateKey);

        Assert.Equal(ResponseCode.Success, delete1Receipt.Status);

        // Confirm deleted account by trying to get info on the deleted account,
        // this will throw an exception.
        var pex = await Assert.ThrowsAsync <PrecheckException>(async() =>
        {
            await fxAccount1.Client.GetAccountInfoAsync(fxAccount1.Record.Address);
        });

        Assert.Equal(ResponseCode.AccountDeleted, pex.Status);

        // Double check the balance on the contract, confirm it has hbars
        var contractBalanceBefore = await fxContract.Client.CallContractWithRecordAsync(new CallContractParams
        {
            Contract     = fxContract.ContractRecord.Contract,
            Gas          = 30000,
            FunctionName = "get_balance"
        });

        Assert.NotNull(contractBalanceBefore);
        Assert.InRange(fxContract.ContractParams.InitialBalance, 1, int.MaxValue);
        Assert.Equal(fxContract.ContractParams.InitialBalance, contractBalanceBefore.CallResult.Result.As <long>());

        // Call the contract, sending to the address of the now deleted account
        var tex = await Assert.ThrowsAsync <TransactionException>(async() =>
        {
            await fxContract.Client.CallContractWithRecordAsync(new CallContractParams
            {
                Contract     = fxContract.ContractRecord.Contract,
                Gas          = 30000,
                FunctionName = "send_to",
                FunctionArgs = new[] { fxAccount1.Record.Address }
            });
        });

        Assert.Equal(ResponseCode.InvalidSolidityAddress, tex.Status);
        Assert.StartsWith("Contract call failed, status: InvalidSolidityAddress", tex.Message);

        // Confirm that the balance on the contract has not changed.
        var contractBalanceAfter = await fxContract.Client.CallContractWithRecordAsync(new CallContractParams
        {
            Contract     = fxContract.ContractRecord.Contract,
            Gas          = 30000,
            FunctionName = "get_balance"
        });

        Assert.NotNull(contractBalanceAfter);
        Assert.Equal(fxContract.ContractParams.InitialBalance, contractBalanceAfter.CallResult.Result.As <long>());

        // Double Check: try to get info on the deleted account,
        // but this will fail because the account is already deleted.
        pex = await Assert.ThrowsAsync <PrecheckException>(async() =>
        {
            // So if this throws an error, why did the above transfer not fail?
            await fxAccount1.Client.GetAccountInfoAsync(fxAccount1.Record.Address);
        });

        Assert.Equal(ResponseCode.AccountDeleted, pex.Status);

        // Delete the Contract, returning any hidden hbars to account number 2
        var deleteContractRecord = await fxContract.Client.DeleteContractAsync(fxContract.ContractRecord.Contract, fxAccount2.Record.Address, fxContract.PrivateKey);

        Assert.Equal(ResponseCode.Success, deleteContractRecord.Status);

        // Check the balance of account number 2, the hBars should be there.
        var info2After = await fxAccount2.Client.GetAccountInfoAsync(fxAccount2.Record.Address);

        Assert.Equal((ulong)fxContract.ContractParams.InitialBalance + info2Before.Balance, info2After.Balance);
    }