Skip to content

[en] VB.NET

Bernardo Ramos edited this page Jul 1, 2020 · 4 revisions

Connections

To be able to communicate with the Aergo blockchain we need to specify the host address and the TCP port.

We create an instance object using the AergoClient class.

Example:

  Dim aergo = New AergoClient()

  ' connect to the blockchain
  aergo.Connect("testnet-api.aergo.io", 7845)

Asynchronous Calls

Blockchains have many advantages but they are slower than traditional databases.

One request using a transaction can take up to 1 second. If you want to make your application responsive while a transaction is being processed on the blockchain you can use asynchronous calls and receive a transaction receipt on a callback function.

As there is no global cross-platform message loop, libaergo has a function to be called to check for incoming results and notifications:

Function ProcessRequests(ByVal Timeout As Integer) As Integer

If your application uses a message loop, put a call to this function on a timer and use the timeout argument 0

Sub OnTimer()
    aergo.ProcessRequests(0)
End Sub

This function returns the number of active requests. If it is zero, you can stop the timer.

You can also use it in a loop and set a value for the timeout.


Accounts

If your application will call smart contract functions (not query) or if it will hold and transfer tokens then it will need an account.

An account is based on a secret+public key pairs. It has an address used to identify the account and it is generated from the public key.

The account objects are allocated by your application. This is the structure:

Structure AergoAccount
    use_ledger As Boolen
    index As UInt32
    privkey() As Byte
    pubkey() As Byte
    address As String
    nonce As ULong
    balance As Double
    state_root() As Byte
    is_updated As Boolen
End Structure

Using Ledger Nano

If the account is stored on a Ledger Nano device you can access it by setting this element:

  account.use_ledger = True

It is also possible to select the Aergo account index on the device:

  account.index = <number>

The default account index is zero.

Private key

When not using a hardware wallet it is required to inform the account private key.

The private/secret key is a random 32 byte byte array.

Your application is responsible for generating a true random private key, storing it into persistent storage and loading it into the account object.

It is very important to to use a very strong source of randomness to generate the private key.

On Linux you can use getrandom if available

On Mac you can use SecRandomCopyBytes

On Windows you can use RtlGenRandom

As not any random 32 bytes are valid private keys, we must verify if the generated random bytes are valid:

  Do
      RandomFill(account.privkey, 32)
  While aergo.CheckPrivateKey(account) = False

Account state

After loading the private key into the account structure we can fill the remaining fields by requesting information about the state of the account to the blockchain.

  Dim success = aergo.GetAccountInfo(account)

Now you can check the account address, the balance, the nonce and the account's state root.

You can check and run the blockchain account info example

For details about the history of transactions for a specific account please access the aergoscan

To add balance to a specific account on the testnet please access the faucet


Transaction Receipts

Transactions are used for value transfers and smart contract execution (call).

A receipt is generated when a transaction is processed by the the blockchain network.

Your application will receive the receipt with this format:

Structure TransactionReceipt
    contractAddress As String
    status As String
    ret As String
    blockNo As ULong
    blockHash() As Byte
    txIndex As Integer
    gasUsed As ULong
    feeUsed As Double
    feeDelegation As Boolean
    Sent As Boolean
End Structure

The received status can be:

  • SUCCESS

    For smart contract calls the result is available in the ret field

  • ERROR

    Failed transfer or smart contract execution. The error message can be found in the ret field

On synchronous calls the receipt is returned as the function return value.

On asynchronous calls the receipt is available on the callback function.

The callback functions used to receive the transaction receipt have this format:

Sub TransactionReceiptCallback(ByVal Context As AergoClient.CallbackState, ByVal Receipt As AergoClient.TransactionReceipt)
  
End Sub

Smart Contracts

Smart contracts are a group of functions stored on the blockchain that can be called by external applications or users.

Aergo uses Lua as the programming language for these contracts and they support SQL.

You can write a smart contract, publish it on the blockchain and call it from your application.

There are 2 types of function calls on smart contracts:

Those who write to the blockchain are named calls

Those who just read from the blockchain are named queries

Calls are made via blockchain transactions and they consume tokens from the caller account.

Queries are made without transactions and they don't need to be signed by an account. They do not require payment for the processing.

Smart Contract Calls

They are used when your application will send data to be processed by and stored into the blockchain.

The application needs to specify the contract address and the smart contract function name. The arguments to the function call are optional.

The arguments can be passed using a variadic function call.

Here is an example of a synchronous call using this method:

    Dim receipt As AergoClient.TransactionReceipt

    receipt = aergo.CallSmartContract(
        account,
        "...",                ' contract_address
        "my_function",        ' function
        123, "testing", 2.5)  ' arguments

You can check and compile the smart contract call example

And here is the asynchronous version of this call:

Sub OnReceipt(ByVal context As AergoClient.CallbackState, ByVal receipt As AergoClient.TransactionReceipt)

End Sub

    Dim ret = aergo.CallSmartContractAsync(
        AddressOf OnReceipt,
        context,
        account,
        "...",                ' contract_address
        "my_function",        ' function
        123, "testing", 2.5)  ' arguments

Don't forget to call the ProcessRequests() function on a timer or a loop to process the incoming result.

You can check and compile the smart contract asynchronous call example

Smart Contract Query

They are used when your application will just read data from the blockchain.

The API are similar to the functions used to smart contract calls.

Here is an example of a synchronous query:

    Dim ret = client.QuerySmartContract(
        "...",                ' contract_address
        "my_function",        ' function
        123, "testing", 2.5)  ' arguments

    If ret.success Then
        Console.WriteLine("Result: " + ret.result)
    Else
        Console.WriteLine("Error: " + ret.result)
    End If

You can check and compile the smart contract query example

And here is the asynchronous version of this call:

Private Sub OnQueryResult(ByVal context As AergoClient.CallbackState, ByVal Success As Boolean, ByVal Result As String)

End Sub

    Dim result = aergo.QuerySmartContractAsync(
        AddressOf OnQueryResult,
        context,
        "...",                ' contract_address
        "my_function",        ' function
        123, "testing", 2.5)  ' arguments

Don't forget to call the ProcessRequests() function on a timer or a loop to process the incoming result.

You can check and compile the smart contract asynchronous query example

Smart contract events

Smart contracts can generate events and your application can subscribe to receive event notifications.

The notification data is presented to the application as a ContractEvent object:

Structure ContractEvent
    contractAddress As String
    eventName As String
    jsonArgs As String
    eventIdx As Integer
    txHash() As Byte
    blockNo As ULong
    blockHash() As Byte
    txIndex As Integer
End Structure

Here is the structure of the callback function and the function used to subscribe to the events:

Sub OnContractEvent(ByVal Context As AergoClient.CallbackState, ByVal ContractEvent As AergoClient.ContractEvent)


End Sub

    Dim result = aergo.SmartContractEventsSubscribe(
        "...",     ' contract_address
        "",        ' event_name - let empty to receive all events
        AddressOf OnContractEvent,
        context)  ' additional data passed to the callback function

Don't forget to call the ProcessRequests() function on a timer or a loop to process the incoming result.

You can check and compile the full example


Transfer

Accounts can hold tokens and they can be transferred to other accounts.

libaergo supports 4 different formats for the amount when transferring tokens.

And there are synchronous and asynchronous versions for these functions.

Amount as Double

Function Transfer(
    ByRef FromAccount As AergoClient.AergoAccount,
    ByVal ToAccount As String,
    ByVal IntegerPart As ULong,
    ByVal DecimalPart As ULong) As AergoClient.TransactionReceipt

Function TransferAsync(
    ByRef FromAccount As AergoClient.AergoAccount,
    ByVal ToAccount As String,
    ByVal IntegerPart As ULong,
    ByVal DecimalPart As ULong,
    ByVal Callback As AergoClient.TransactionReceiptCallback,
    ByVal Context As AergoClient.CallbackState) As Boolean

Amount as integer and decimal parts

Note: decimal part with 18 digits!

Example: in 3.5 the integer part is 3 and the decimal part is 500000000000000000

Function Transfer(
    ByRef FromAccount As AergoClient.AergoAccount,
    ByVal ToAccount As String,
    ByVal Value As String) As AergoClient.TransactionReceipt

Function TransferAsync(
    ByRef FromAccount As AergoClient.AergoAccount,
    ByVal ToAccount As String,
    ByVal Value As String,
    ByVal Callback As AergoClient.TransactionReceiptCallback,
    ByVal Context As AergoClient.CallbackState) As Boolean

Amount as String

It must be null terminated. The unit is aergo

Example: "130.25"

Function Transfer(
    ByRef FromAccount As AergoClient.AergoAccount,
    ByVal ToAccount As String,
    ByVal Value As Double) As AergoClient.TransactionReceipt

Function TransferAsync(
    ByRef FromAccount As AergoClient.AergoAccount,
    ByVal ToAccount As String,
    ByVal Value As BigInteger,
    ByVal Callback As AergoClient.TransactionReceiptCallback,
    ByVal Context As AergoClient.CallbackState) As Boolean

Amount as BigInteger

Function Transfer(
    ByRef FromAccount As AergoClient.AergoAccount,
    ByVal ToAccount As String,
    ByVal Value As Double) As AergoClient.TransactionReceipt

Function TransferAsync(
    ByRef FromAccount As AergoClient.AergoAccount,
    ByVal ToAccount As String,
    ByVal Value As BigInteger,
    ByVal Callback As AergoClient.TransactionReceiptCallback,
    ByVal Context As AergoClient.CallbackState) As Boolean

You can check and compile the transfer example as well as the asynchronous transfer example

Clone this wiki locally