用 Elixir 交互 Aptos | Move dApp 极速入门

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

mix.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 调取函数与读取事件

我们以 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}"

结果如下:

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, []}

生成 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"
 }}

以上内容均转载自互联网,不代表AptosNews立场,不是投资建议,投资有风险,入市需谨慎,如遇侵权请联系管理员删除。

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023年7月21日
下一篇 2023年7月21日

相关文章

发表回复

登录后才能评论
微信扫一扫
百度扫一扫
本站没有投资建议,投资有风险,入市需谨慎。