前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >7.MOVE从入门到实战-Aptos测试网发起一笔交易

7.MOVE从入门到实战-Aptos测试网发起一笔交易

作者头像
Tiny熊
发布2022-11-07 11:12:54
4920
发布2022-11-07 11:12:54
举报

本文作者:木头[1]

创建 node 项目

package.json依赖包

代码语言:javascript
复制
"dependencies": {
  "@types/node": "^17.0.21",
  "aptos": "^1.3.7",
  "cross-fetch": "^3.1.5",
  "fmt": "^2.0.0",
  "js-sha3": "^0.8.0",
  "prettier": "^2.7.1",
  "tweetnacl": "^1.0.3"
},
"devDependencies": {
  "ts-node": "^10.9.1",
  "typescript": "^4.7.4"
}

创建帐户

引入Aptos提供生成地址的方法

代码语言:javascript
复制
import { AptosAccount, TxnBuilderTypes, BCS, MaybeHexString } from "aptos";
const account = new AptosAccount();
console.log(`地址: ${account.address()} 私钥种子: ${Buffer.from(account.signingKey.secretKey).toString("hex").slice(0, 64)}`);

水龙头领取代币

在发起交易之前先领取一下测试代币作手续费

代码语言:javascript
复制
//aptos测试节点URL  REST API地址
export const NODE_URL = "https://fullnode.devnet.aptoslabs.com";
//aptos水龙头URL
export const FAUCET_URL = "https://faucet.devnet.aptoslabs.com";

//Aptos客户端 水龙头客户端方法
import { AptosClient, FaucetClient } from "aptos";

//创建水龙头客户端
const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL);

//领取2万个测试代币
await faucetClient.fundAccount(account.address(), 20000);

查询余额

接口:getAccountResource()[2]

代码语言:javascript
复制
//创建ptos客户端
const client = new AptosClient(NODE_URL);

export async function accountBalance(accountAddress: MaybeHexString): Promise<number | null> {
  const resource = await client.getAccountResource(accountAddress, "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>");
  if (resource == null) {
    return null;
  }
  return parseInt((resource.data as any)["coin"]["value"]);
}

发起交易

将给定数量的代币金额从给定的帐户转移到收件人的帐户地址。接口:TxnBuilderTypes.TypeTagStruct()[3]

TxnBuilderTypes.ScriptFunction.natural()[4]

代码语言:javascript
复制
async function transfer(accountFrom: AptosAccount, recipient: MaybeHexString, amount: number): Promise<string> {
  //类型标记结构
  const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString("0x1::aptos_coin::AptosCoin"));

  //事务负载脚本函数
  const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
    TxnBuilderTypes.EntryFunction.natural(
      "0x1::coin",
      "transfer",
      [token],
      [BCS.bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(recipient)), BCS.bcsSerializeUint64(amount)],
    ),
  );

  const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([
    client.getAccount(accountFrom.address()),
    client.getChainId(),
  ]);

  //原始事务处理
  const rawTxn = new TxnBuilderTypes.RawTransaction(
    TxnBuilderTypes.AccountAddress.fromHex(accountFrom.address()),
    BigInt(sequenceNumber),
    entryFunctionPayload,
    1000n,
    1n,
    BigInt(Math.floor(Date.now() / 1000) + 10),
    new TxnBuilderTypes.ChainId(chainId),
  );

  //生成BCS事务
  const bcsTxn = AptosClient.generateBCSTransaction(accountFrom, rawTxn);
  //提交已签名的BCS事务
  const pendingTxn = await client.submitSignedBCSTransaction(bcsTxn);

  return pendingTxn.hash;
}

完整 ts 代码

代码语言:javascript
复制
//节点URL  REST API地址
export const NODE_URL = "https://fullnode.devnet.aptoslabs.com";
//水龙头URL
export const FAUCET_URL = "https://faucet.devnet.aptoslabs.com";

//生成账号接口
import { AptosAccount, TxnBuilderTypes, BCS, MaybeHexString } from "aptos";

//Aptos客户端 水龙头客户端
import { AptosClient, FaucetClient } from "aptos";

//创建节点客户端
const client = new AptosClient(NODE_URL);
const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL);


//Helper方法返回与帐户关联的硬币余额
export async function accountBalance(accountAddress: MaybeHexString): Promise<number | null> {
  const resource = await client.getAccountResource(accountAddress, "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>");
  if (resource == null) {
    return null;
  }

  return parseInt((resource.data as any)["coin"]["value"]);
}

/**
 * 将给定的硬币金额从给定的帐户从转移到收件人的帐户地址。
 */
async function transfer(accountFrom: AptosAccount, recipient: MaybeHexString, amount: number): Promise<string> {
  //类型标记结构
  const token = new TxnBuilderTypes.TypeTagStruct(TxnBuilderTypes.StructTag.fromString("0x1::aptos_coin::AptosCoin"));

  //事务负载脚本函数
  const entryFunctionPayload = new TxnBuilderTypes.TransactionPayloadEntryFunction(
    TxnBuilderTypes.EntryFunction.natural(
      "0x1::coin",
      "transfer",
      [token],
      [BCS.bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(recipient)), BCS.bcsSerializeUint64(amount)],
    ),
  );

  const [{ sequence_number: sequenceNumber }, chainId] = await Promise.all([
    client.getAccount(accountFrom.address()),
    client.getChainId(),
  ]);

  //原始事务处理
  const rawTxn = new TxnBuilderTypes.RawTransaction(
    TxnBuilderTypes.AccountAddress.fromHex(accountFrom.address()),
    BigInt(sequenceNumber),
    entryFunctionPayload,
    1000n,
    1n,
    BigInt(Math.floor(Date.now() / 1000) + 10),
    new TxnBuilderTypes.ChainId(chainId),
  );

  //生成BCS事务
  const bcsTxn = AptosClient.generateBCSTransaction(accountFrom, rawTxn);
  //提交已签名的BCS事务
  const pendingTxn = await client.submitSignedBCSTransaction(bcsTxn);

  return pendingTxn.hash;
}


async function main() {
  //创建两个账户,A和B,并为A而不是B提供资金
  const a = new AptosAccount();
  const b = new AptosAccount();

  console.log("\n=== 地址 ===");
  console.log(
    `A: ${a.address()} Key: ${Buffer.from(a.signingKey.secretKey).toString("hex").slice(0, 64)}`,
  );
  console.log(`B: ${b.address()} Key: ${Buffer.from(b.signingKey.secretKey).toString("hex").slice(0, 64)}`);

  //水龙头领取代币
  await faucetClient.fundAccount(a.address(), 20000);
  await faucetClient.fundAccount(b.address(), 0);

  console.log("\n=== 初始余额 ===");
  console.log(`A: ${await accountBalance(a.address())}`);
  console.log(`B: ${await accountBalance(b.address())}`);

  // A 转账给 B 1000个硬币
  const txHash = await transfer(a, b.address(), 1000);
  await client.waitForTransaction(txHash);

  console.log("\n=== 账户余额 ===");
  console.log(`A: ${await accountBalance(a.address())}`);
  console.log(`B: ${await accountBalance(b.address())}`);

}

if (require.main === module) {
  main();
}

运行程序

执行命令:$ node --loader ts-node/esm transaction.ts输出:

代码语言:javascript
复制
=== 地址 ===
A: 0xacc02f55737a690e3c452bd84fa6adee1b26bdcecc2938f522b931f6bd1062c2 Key: ae299733eddfb2fbac2cb926f81d24aecc7532c5baae228aa5964e2a87fd5b80
B: 0xeeb6b0446439df55bbbc22c0dbd9415dfe9994a21137a9e3c4f1e23007f7d709 Key: 69a9f4e7ed37252569a07aca4f763dcbe93c10203fe5773a0fd6551f7104fdb9

=== 初始余额 ===
A: 20000
B: 0

=== 账户余额 ===
A: 18996
B: 1000

区块浏览器

https://explorer.devnet.aptos.dev/[5]

参考资料

[1]

木头: https://learnblockchain.cn/people/3015

[2]

getAccountResource(): https://aptos-labs.github.io/ts-sdk-doc/classes/AptosClient.html#getAccountResource

[3]

TxnBuilderTypes.TypeTagStruct(): https://aptos-labs.github.io/ts-sdk-doc/classes/TxnBuilderTypes.TypeTagStruct.html

[4]

TxnBuilderTypes.ScriptFunction.natural(): https://aptos-labs.github.io/ts-sdk-doc/classes/TxnBuilderTypes.ScriptFunction.html

[5]

https://explorer.devnet.aptos.dev/: https://explorer.devnet.aptos.dev/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建 node 项目
  • 创建帐户
  • 水龙头领取代币
  • 查询余额
  • 发起交易
  • 完整 ts 代码
  • 运行程序
  • 区块浏览器
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档