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