Interacting with Elixir Aptos | Move dApp Getting Started Quickly

NonceGeekDAO 长期聚焦于 Move 生态与 Elixir 函数式编程语言。

https://github.com/NonceGeek/

web3_move_ex 是 NonceGeekDAO 开发的,泛 Move 生态的 Elixir SDK,目前已完成对Aptos的基础支持。

本篇文章案例可见:

https://github.com/NonceGeek/web3_move_ex_example

Aptos 已完成功能列表:

  • Acct Operations(账户相关操作)
  • Read Resource(读取资源)
  • Read Events(读取事件)
  • Call Func(调取函数)
  • Func Parser(解析字符串格式的函数,如0xdea79e568e00066f60fbfe6ac6d8a9ef2fabbeadc6aae1ec9158d50f6efe4ac8::addr_aggregator::create_addr_aggregator(u64,vector<string>))

0x01 安装

创建一个新的示例项目:

$ mix new web3_move_ex_example
$ # 或者 clone 现成的 github repo:
$ git clone https://github.com/NonceGeek/web3_move_ex_example.git

existmix.exs 中添加最新版本的web3_move_ex::

defp deps do
    [
			{:web3_move_ex, "~> 0.4.0"}
    ]
end

打开交互式界面:

$ iex -S mix

0x02 账户相关

我们可以通过随机种子来生成账户:

alias Web3MoveEx.Aptos
{:ok, acct} = Aptos.generate_keys()

也可以通过私钥来生成:

{:ok, acct} = Aptos.generate_keys("0xffc207d0666ca82eac4e2238d0cf15f963a03ec6a9daa617dc035b7228de1f28")

创建连接节点的 client::

{:ok, client} = Aptos.connect(:testnet)

给账户注入一些 faucet::

Aptos.get_faucet(client, acct)

获取余额:

Aptos.get_balance(client, acct)

可以看到获取 faucet 成功了:

iex(10)> Aptos.get_balance(client, acct)
%{
  coin: %{value: "100000000"},
  deposit_events: %{
    counter: "1",
    guid: %{
      id: %{
        addr: "0xe59f44953723d5a8e26df9d3d4a613a2da3ff9f7dc4214dc281e10a244f39e3f",
        creation_num: "2"
      }
    }
  },
  frozen: false,
  withdraw_events: %{
    counter: "0",
    guid: %{
      id: %{
        addr: "0xe59f44953723d5a8e26df9d3d4a613a2da3ff9f7dc4214dc281e10a244f39e3f",
        creation_num: "3"
      }
    }
  }
}

我们可以把刚才的一系列步骤打包成一个函数:

def gen_acct_and_get_faucet(network_type) do
  {:ok, acct} = Aptos.generate_keys()
  {:ok, client} = Aptos.connect(network_type)
  {:ok, _res} = Aptos.get_faucet(client, acct)
  Process.sleep(2000)  # 用 2 秒等待交易成功
  %{res: Aptos.get_balance(client, acct), acct: acct}
end

函数执行结果:

iex(7)> %{acct: acct} = Web3MoveExExample.gen_acct_and_get_faucet(:testnet)
%{
  acct: #Account<0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f>,
  res: %{
    coin: %{value: "100000000"},
    deposit_events: %{
      counter: "1",
      guid: %{
        id: %{
          addr: "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f",
          creation_num: "2"
        }
      }
    },
    frozen: false,
    withdraw_events: %{
      counter: "0",
      guid: %{
        id: %{
          addr: "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f",
          creation_num: "3"
        }
      }
    }
  }
}

0x03 调取函数与读取事件

We are based on MoveDID在测试网络上的合约为例,演示如何通过web3_move_ex来进行合约调用。

MoveDID Repo:https://github.com/NonceGeek/MoveDID

Smart Contract on Testnet:

0x06195d43edde4b1cd3a96f7838686b9b12b51023cd388dfb21f123b350f4ec46

我们可以通过 func_string 来生成 func:

import Web3MoveEx.Aptos
addr= "0x06195d43edde4b1cd3a96f7838686b9b12b51023cd388dfb21f123b350f4ec46" # 合约地址
init_func_str = "#{addr}::init::init(u64, string)"
{:ok, init_func} = ~a"#{init_func_str}"

The results are as follows:

iex(5)> {:ok, init_func} = ~a"#{init_func_str}"
{:ok,
 %Web3MoveEx.Aptos.Types.Function{
   address: <<6, 25, 93, 67, 237, 222, 75, 28, 211, 169, 111, 120, 56,
     104, 107, 155, 18, 181, 16, 35, 205, 56, 141, 251, 33, 241, 35,
     179, 80, 244, 236, 70>>,
   address_encoded: "0x06195d43edde4b1cd3a96f7838686b9b12b51023cd388dfb21f123b350f4ec46",
   is_entry: true,
   module: "init",
   name: "init",
   param_names: [],
   params: [:u64, :string],
   return: [],
   type_params: [],
   visibility: :public
 }}

可以顺便检查一下events的功能,按照合约逻辑,新添加一个DID,会在contract_owner下生成相应的事件。

Aptos.build_event_path(client, addr, "#{addr}::addr_aggregator::CreateAddrAggregatorEventSet", "create_addr_aggregator_events")
# 这个函数生成的地址可以直接用浏览器访问.
Aptos.get_events(client, addr, "#{addr}::addr_aggregator::CreateAddrAggregatorEventSet", "create_addr_aggregator_events")
# 这个函数可以拿到 Event 结果.

Result:

iex(13)> Aptos.get_events(client, addr, "#{addr}::addr_aggregator::CreateAddrAggregatorEventSet", "create_addr_aggregator_events")
{:ok, []}

generating payload::

payload = Aptos.call_function(f, [], [1, "testAcct"])

提交交易:

Aptos.submit_txn_with_auto_acct_updating(client, acct, payload)
# 方法 0x01:自动更新 acct 的信息
# Aptos.submit_txn(client, acct, payload)
# 方法 0x02:不自动更新 acct 的信息

执行结果:

iex(15)> Aptos.submit_txn_with_auto_acct_updating(client, acct, payload)
{:ok,
 %{
   expiration_timestamp_secs: "1679451173",
   gas_unit_price: "1000",
   hash: "0x931c2821df3e6c9c40bf00d5ed7e20aa1172a053d3c3d658a9f7bd31f17d91f6",
   max_gas_amount: "2000",
   payload: %{
     arguments: ["1", "testAcct"],
     function: "0x6195d43edde4b1cd3a96f7838686b9b12b51023cd388dfb21f123b350f4ec46::init::init",
     type: "entry_function_payload",
     type_arguments: []
   },
   sender: "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f",
   sequence_number: "0",
   signature: %{
     public_key: "0x361c4395cc87cf951dc5f879bdf2c2f91df3078c9a2ee4b5bf9892243a24a5fb",
     signature: "0x94f9cbf17c5095e76ea30a88d6683c9951fbfa3b1e261ca6b4722fac985946dcc0f5e7a8c03e6b322f39b102874484b620cf0943c672eadd4fd9b3505e65f804",
     type: "ed25519_signature"
   }
 }}

在浏览器上查看,交易执行成功:

我们也可以通过check_tx_res_by_hash查看:

Aptos.check_tx_res_by_hash(client, hash) # return true or false

我们同样可以将call_fun_init的过程封装为一个函数:

 def call_func_init(client, acct, contract_addr,  did_type, description) do
    {:ok, f} = gen_func_init(contract_addr)
    payload = Aptos.call_function(f, [], [did_type, description])
    {:ok, %{hash: hash} = tx} = Aptos.submit_txn_with_auto_acct_updating(client, acct, payload)
    Process.sleep(2000)  # 用 2 秒等待交易成功
    res = Aptos.check_tx_res_by_hash(client, hash)
    %{res: res, tx: tx}
  end
  
  def gen_func_init(contract_addr) do
    init_func_str = "#{contract_addr}::init::init(u64, string)"
    ~a"#{init_func_str}"
  end

执行结果:

iex(22)> Web3MoveExExample.call_func_init(client, acct, addr, 1, "test Acct")
%{
  res: true,
  tx: %{
    expiration_timestamp_secs: "1679475296",
    gas_unit_price: "1000",
    hash: "0x73687a7e4c953f3cf13a768fe03560a61c06615fa8c089888f23cd3ccd8dc6e8",
    max_gas_amount: "2000",
    payload: %{
      arguments: ["1", "test Acct"],
      function: "0x6195d43edde4b1cd3a96f7838686b9b12b51023cd388dfb21f123b350f4ec46::init::init",
      type: "entry_function_payload",
      type_arguments: []
    },
    sender: "0xc193cd62bab00790d40265505ce894552c14a3693aca9bc2310ee0ecdc53780b",
    sequence_number: "0",
    signature: %{
      public_key: "0x6bfa0d62dd63ea8a4291ffec10fc448ab554188d7765a9faf1b0992dbb199c38",
      signature: "0xc8a9d4368a0cc2daff3add7162745990d3bd9c33ec6f1112b5dfe45cdd25d4fdf5d19a361048b67081e3ce9c242c93266af4736d8c86541906e08c2ef387ef05",
      type: "ed25519_signature"
    }
  }
}

此时再次执行 get_events,会发现 events 成功生成:

iex(16)> Aptos.get_events(client, addr, "#{addr}::addr_aggregator::CreateAddrAggregatorEventSet", "create_addr_aggregator_events")
{:ok,
 [
   %{
     data: %{
       description: "testAcct",
       key_addr: "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f",
       type: "1"
     },
     guid: %{
       account_address: "0x6195d43edde4b1cd3a96f7838686b9b12b51023cd388dfb21f123b350f4ec46",
       creation_number: "4"
     },
     sequence_number: "0",
     type: "0x6195d43edde4b1cd3a96f7838686b9b12b51023cd388dfb21f123b350f4ec46::addr_aggregator::CreateAddrAggregatorEvent",
     version: "473098605"
   }
 ]}

0x04 查看资源

打开浏览器访问:

https://explorer.aptoslabs.com/account/0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f/resources

这个资源我们同样可以通过 web3_move_ex获取到:

Aptos.get_resource(client, account.address_hex, "#{addr}::addr_aggregator::AddrAggregator")

结果:

iex(20)> Aptos.get_resource(client, "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f", "#{addr}::addr_aggregator::AddrAggregator")
{:ok,
 %{
   data: %{
     add_addr_events: %{
       counter: "0",
       guid: %{
         id: %{
           addr: "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f",
           creation_num: "4"
         }
       }
     },
     addr_infos_map: %{
       handle: "0xbae0b5ae8c373db15ca2f71a18f92ed3ed363e5730cf3f8a90791c04ff6908da"
     },
     addrs: [],
     delete_addr_events: %{
       counter: "0",
       guid: %{
         id: %{
           addr: "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f",
           creation_num: "7"
         }
       }
     },
     description: "testAcct",
     key_addr: "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f",
     max_id: "0",
     modified_counter: "0",
     type: "1",
     update_addr_events: %{
       counter: "0",
       guid: %{
         id: %{
           addr: "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f",
           creation_num: "6"
         }
       }
     },
     update_addr_signature_events: %{
       counter: "0",
       guid: %{
         id: %{
           addr: "0xedf8dcb761e7ee7884e5a94d1f9b330f7a3ed09317bebe163738c31dc67e446f",
           creation_num: "5"
         }
       }
     }
   },
   type: "0x6195d43edde4b1cd3a96f7838686b9b12b51023cd388dfb21f123b350f4ec46::addr_aggregator::AddrAggregator"
 }}

The above content are reproduced from the Internet, does not represent the position of AptosNews, is not investment advice, investment risk, the market need to be cautious, in case of infringement, please contact the administrator to delete.

Like (0)
Donate WeChat Sweep WeChat Sweep Alipay Sweep Alipay Sweep
Previous July 21, 2023
Next July 21, 2023

Related posts

Leave a Reply

Please Login to Comment
WeChat Sweep
Baidu Sweep

Subscribe to AptosNews

Subscribe to AptosNews to stay on top of Aptos.


This will close in 25 seconds

This site has no investment advice, Investment risk, Enter the market with caution.