网站 实名认证,广元网站建设工作室,手机网站触摸版,四川企业网站建设文章目录 一、安装node1.1 在 macOS 上管理 Node版本1.1.1 安装 nvm1.1.2 验证 nvm 是否安装成功1.1.3 使用 nvm 安装/切换 Node.js 版本1.1.4 卸载 Node.js 版本 1.2 在 windows 上管理 Node版本1.2.1 安装 nvm-windows1.2.2 安装 Node.js 版本1.2.3 切换 Node.js 版本1.2.4 卸… 文章目录 一、安装node1.1 在 macOS 上管理 Node版本1.1.1 安装 nvm1.1.2 验证 nvm 是否安装成功1.1.3 使用 nvm 安装/切换 Node.js 版本1.1.4 卸载 Node.js 版本 1.2 在 windows 上管理 Node版本1.2.1 安装 nvm-windows1.2.2 安装 Node.js 版本1.2.3 切换 Node.js 版本1.2.4 卸载 Node.js 版本1.2.5 检查当前 Node.js 版本 二、安装 aos三、使用AOS3.1 发送第一个命令3.2 发送消息3.3 向 Morpheus 发送消息3.4 收件箱 四、操作Arweave的token4.1 发布一个Arweave的token4.2 使用golang调用token4.3 获取消息信息 一、安装node
1.1 在 macOS 上管理 Node版本
在 macOS 上管理 Node.js 版本通常使用 nvmNode Version Manager是最便捷的方式。以下是安装和使用 nvm 来管理 Node.js 版本的步骤
1.1.1 安装 nvm
打开终端并运行以下命令来安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
运行上述命令后按照提示操作安装过程会将 nvm 的路径添加到 shell 配置文件如 .bashrc, .bash_profile, .zshrc 等中。 注意如果你使用的是 Zsh 作为默认终端可能需要编辑 .zshrc 文件如果使用的是 Bash可能需要编辑 .bash_profile 或 .bashrc。 在安装完成后执行以下命令来重新加载 shell 配置文件
source ~/.bashrc # 或者 source ~/.zshrc视具体情况而定1.1.2 验证 nvm 是否安装成功
在终端运行以下命令来检查是否成功安装
nvm --version如果返回 nvm 版本号则说明安装成功。
1.1.3 使用 nvm 安装/切换 Node.js 版本 查看可用的 Node.js 版本 nvm ls-remote 安装特定版本的 Node.js nvm install version
例如安装 Node.js 21.x
nvm install v21.0.0切换到特定版本的 Node.js nvm use version
例如切换到 Node.js 22.x
nvm use v22.0.0查看当前已安装的 Node.js 版本 nvm ls 设置默认 Node.js 版本 nvm alias default version
例如设置默认版本为 22.x
nvm alias default v22.0.0这样每次打开终端时系统会自动使用你设定的默认版本。 1.1.4 卸载 Node.js 版本
如果需要卸载某个 Node.js 版本可以使用以下命令
nvm uninstall version例如
nvm uninstall 221.2 在 windows 上管理 Node版本
在 Windows 上管理 Node.js 版本常用的工具是 nvm-windows这是 Node Version Manager (NVM) 的 Windows 版本。使用它可以轻松安装、切换和管理多个 Node.js 版本。
1.2.1 安装 nvm-windows 下载 nvm-windows前往 nvm-windows GitHub 主页 - 下载最新的 .zip 文件或 .exe 安装文件。 安装运行下载的 .exe 文件按照安装向导的提示进行安装。建议选择默认的安装路径以免出现权限问题。
1.2.2 安装 Node.js 版本
查看可用的 Node.js 版本 安装好 nvm 后打开命令行如 PowerShell 或 CMD输入以下命令来查看可安装的 Node.js 版本列表 nvm list available安装指定版本的 Node.js 选择一个版本号并使用以下命令进行安装例如安装 Node.js 16.13.0 nvm install 16.13.0查看已安装的版本 可以查看系统上已经安装的 Node.js 版本 nvm list1.2.3 切换 Node.js 版本
使用指定版本的 Node.js 如果你已经安装了多个版本的 Node.js你可以使用以下命令切换到所需的版本 nvm use 16.13.0使用该命令后你的 Node.js 和 npm 都会切换到该版本。 1.2.4 卸载 Node.js 版本
卸载不需要的版本 如果你不再需要某个版本的 Node.js可以通过以下命令卸载 nvm uninstall 16.13.01.2.5 检查当前 Node.js 版本
确认当前的 Node.js 版本 使用 node -v 来查看当前使用的 Node.js 版本 node -v
二、安装 aos 完成 NodeJS 安装后只需安装 aos 并运行它: npm i -g https://preview_ao.g8way.io 卸载aos服务 npm uninstall -g permaweb/aos 安装完成后我们运行命令即可启动一个新的 aos 进程 aos aos 命令运行时其实是你在使用密钥文件向 aos 验证你的身份的。如果没有指定aos 会默认生成一个新的密钥文件并将其存储在本地 ~/.aos.json。如果你有 Arweave 钱包可以使用 --wallet [location] 参数使用指定钱包。 刚刚我们启动的程序实例是本地客户端它已准备好将消息发送到你的新进程ao 计算机内的进程。
连接后我们会看到以下内容 _____ _______ _____ /\ \ /::\ \ /\ \ /::\ \ /::::\ \ /::\ \ /::::\ \ /::::::\ \ /::::\ \ /::::::\ \ /::::::::\ \ /::::::\ \ /:::/\:::\ \ /:::/~~\:::\ \ /:::/\:::\ \ /:::/__\:::\ \ /:::/ \:::\ \ /:::/__\:::\ \ /::::\ \:::\ \ /:::/ / \:::\ \ \:::\ \:::\ \ /::::::\ \:::\ \ /:::/____/ \:::\____\ ___\:::\ \:::\ \ /:::/\:::\ \:::\ \ |:::| | |:::| | /\ \:::\ \:::\ \
/:::/ \:::\ \:::\____\|:::|____| |:::| |/::\ \:::\ \:::\____\
\::/ \:::\ /:::/ / \:::\ \ /:::/ / \:::\ \:::\ \::/ /\/____/ \:::\/:::/ / \:::\ \ /:::/ / \:::\ \:::\ \/____/ \::::::/ / \:::\ /:::/ / \:::\ \:::\ \ \::::/ / \:::\__/:::/ / \:::\ \:::\____\ /:::/ / \::::::::/ / \:::\ /:::/ / /:::/ / \::::::/ / \:::\/:::/ / /:::/ / \::::/ / \::::::/ / /:::/ / \::/____/ \::::/ / \::/ / ~~ \::/ / \/____/ \/____/ Welcome to AOS: Your operating system for AO, the decentralized open access supercomputer.
Type .load-blueprint chat to join the community chat and ask questions!AOS Client Version: 2.0.0. 2024
Type Ctrl-C twice to exitYour AOS process: 9qyG3YAlPYt9SBns5zwrbIZGvYVdM8s86fIi2qw8jbsdefaultaos-2.0.0[Inbox:8] 三、使用AOS
3.1 发送第一个命令
我们所拥有的 aos 进程已经驻留在 ao 计算机内部的服务器上等待接收和执行你的命令。
为了让开发更加的简单aos 使用 Lua 编程语言撰写命令。 还没学过 Lua 不要着急 这是一种超级简单、友好的语言。 看完本手册后你就顺带学会 Lua。
让我们打破僵局并输入
defaultaos-2.0.0[Inbox:8] Hello, ao!然后按 [Enter] 键。 你会看到 shell 签名并发布消息请求结果然后打印结果如下所示
Hello, ao!3.2 发送消息 Send({ Target process ID, Data Hello World! })SendSend 是 aos 中全局函数用于发送消息。Target如果要将消息发送到特定进程请在消息中包含 Target 字段。DataData 是你希望目标进程接收的文本消息。 在此示例中消息是 Hello World
3.3 向 Morpheus 发送消息
存储 Morpheus 的进程 ID
我们将使用下面提供的进程 ID 并将其存储为名为 Morpheus 的变量。
wu_tAUDUveetQZpcN8UxHt51d9dyUkI4Z-MfQV8LnUU通过复制上面的进程 ID 并在 aos CLI 中运行以下命令以便将其存储为变量
Morpheus wu_tAUDUveetQZpcN8UxHt51d9dyUkI4Z-MfQV8LnUU这会将进程 ID 存储为名为 Morpheus 的变量从而更轻松地与特定进程 ID 进行交互。 创建 Morpheus 变量时我们应该看到的唯一响应是 undefined。 这是预料之中的。 要检查变量是否已成功创建请输入 Morpheus 并按 Enter。 我们应该会看到你存储的进程 ID。 检查 Morpheus 变量
-- 通过输入 Morpheus 检查 Morpheus 变量
Morpheus
-- 预期结果:
wu_tAUDUveetQZpcN8UxHt51d9dyUkI4Z-MfQV8LnUU-- 如果 undefined 被返回,
-- 那么变量没有创建成功。向 Morpheus 发送消息
获取 Morpheus 的进程 ID 并将其存储在变量中后我们就可以与它进行通信了。 为此你可以使用 Send 函数。 Morpheus 本身就是 ao 中运行的一个并行进程。 他使用一系列 handler 接收和发送消息。 让我们向他发送消息看看会发生什么。
Send({ Target Morpheus, Data Morpheus? })我们的 Target 是 Morpheus这是我们之前使用 Morpheus 进程 ID 定义的变量。 Data 是我们要发送给 Morpheus 的消息。 在这里它是 Morpheus?。
预期结果
-- 我们的消息命令
Send({ Target Morpheus, Data Morpheus?})
-- 消息已添加到发件箱
message added to outbox
-- 从 Morpheus 的进程 ID 收到一条新消息
New Message From BWM...ulw: Data I am here. You are f3.4 收件箱
收件箱 是我们从其他进程接收消息的地方。
让我们检查收件箱看看我们收到了多少条消息。
在 aos CLI 中输入以下命令
#Inbox返回值示范:
-- 你的 收件箱 命令
#Inbox
-- 该命令将返回我们收件箱中的消息数量
16在上面的示例中返回为 16表示收件箱中有十六封邮件。
由于我们主要是为了寻找 Morpheus 的回复因此我们假设他的消息是最后收到的消息。要阅读收件箱中的最后一条消息请键入以下命令
Inbox[#Inbox].Data该命令允许我们将数据与消息分离并且仅读取特定数据字段的内容。
预期返回
-- 你的 Inbox[x].Data 命令
Inbox[#Inbox].Data
-- 该命令将返回消息的 Data 字段。
-- Data 通常代表基于文本的消息
-- 从一个进程接收到另一进程。
I am here. You are finally awake. Are you ready to see how far the rabbit hole goes?四、操作Arweave的token
4.1 发布一个Arweave的token
// 引入lua库
// bint用于处理大整数
// json用于处理 JSON 数据local bint require(.bint)(256)
local json require(json)// 定义工具函数
// add: 将两个数相加返回字符串形式的结果。
// subtract: 从一个数中减去另一个数返回字符串形式的结果。
// toBalanceValue: 将一个数字转换为字符串用于表示余额。
// toNumber: 将字符串形式的数字转换为 Lua 数字。local utils {add function(a, b)return tostring(bint(a) bint(b))end,subtract function(a, b)return tostring(bint(a) - bint(b))end,toBalanceValue function(a)return tostring(bint(a))end,toNumber function(a)return bint.tonumber(a)end
}// 全局变量这部分属于合约本身内部的状态属于当前process 独立的状态收到消息并且处理以后呢将会改变这些状态
// 定义代币的基本信息版本、精度小数位数、初始余额、总供应量、名称、符号和 logo。
// 使用 or 操作符为未定义的变量提供默认值。Variant 0.0.3Denomination Denomination or 12
Balances Balances or { [ao.id] utils.toBalanceValue(10000 * 10 ^ Denomination) }
TotalSupply TotalSupply or utils.toBalanceValue(10000 * 10 ^ Denomination)
Name Name or Points Coin
Ticker Ticker or PNTS
Logo Logo or SBCCXwwecBlDqRLUjb8dYABExTJXLieawf7m2aBJ-KY// info处理“信息”请求返回代币的基本信息。
Handlers.add(info, Handlers.utils.hasMatchingTag(Action, Info), function(msg)if msg.reply thenmsg.reply({Name Name,Ticker Ticker,Logo Logo,Denomination tostring(Denomination)})elseSend({Target msg.From, Name Name,Ticker Ticker,Logo Logo,Denomination tostring(Denomination)})end
end)// balance处理查询余额的请求根据接收者的不同返回相应的余额。
Handlers.add(balance, Handlers.utils.hasMatchingTag(Action, Balance), function(msg)local bal 0if (msg.Tags.Recipient) thenif (Balances[msg.Tags.Recipient]) thenbal Balances[msg.Tags.Recipient]endelseif msg.Tags.Target and Balances[msg.Tags.Target] thenbal Balances[msg.Tags.Target]elseif Balances[msg.From] thenbal Balances[msg.From]endif msg.reply thenmsg.reply({Balance bal,Ticker Ticker,Account msg.Tags.Recipient or msg.From,Data bal})elseSend({Target msg.From,Balance bal,Ticker Ticker,Account msg.Tags.Recipient or msg.From,Data bal})end
end)// balances用于查询所有账户的余额
Handlers.add(balances, Handlers.utils.hasMatchingTag(Action, Balances),function(msg) if msg.reply thenmsg.reply({ Data json.encode(Balances) })else Send({Target msg.From, Data json.encode(Balances) }) endend)// transfer处理代币转账请求检查余额是否足够如果足够则进行转账并发送通知。
Handlers.add(transfer, Handlers.utils.hasMatchingTag(Action, Transfer), function(msg)// transfer参数的检查确保 接收者 和 数量 的类型正确且数量大于0assert(type(msg.Recipient) string, Recipient is required!)assert(type(msg.Quantity) string, Quantity is required!)assert(bint.__lt(0, bint(msg.Quantity)), Quantity must be greater than 0)// 检查发件人和接收人的余额如果不存在则初始化为0。if not Balances[msg.From] then Balances[msg.From] 0 endif not Balances[msg.Recipient] then Balances[msg.Recipient] 0 end// 检查发送者的余额是否足够进行转账if bint(msg.Quantity) bint(Balances[msg.From]) then// 从发送者余额中扣除数量并将该数量加到接收者余额。Balances[msg.From] utils.subtract(Balances[msg.From], msg.Quantity)Balances[msg.Recipient] utils.add(Balances[msg.Recipient], msg.Quantity)// 通知发送者及接收者 转账通知if not msg.Cast thenlocal debitNotice {Action Debit-Notice,Recipient msg.Recipient,Quantity msg.Quantity,Data Colors.gray ..You transferred ..Colors.blue .. msg.Quantity .. Colors.gray .. to .. Colors.green .. msg.Recipient .. Colors.reset}local creditNotice {Target msg.Recipient,Action Credit-Notice,Sender msg.From,Quantity msg.Quantity,Data Colors.gray ..You received ..Colors.blue .. msg.Quantity .. Colors.gray .. from .. Colors.green .. msg.From .. Colors.reset}for tagName, tagValue in pairs(msg) doif string.sub(tagName, 1, 2) X- thendebitNotice[tagName] tagValuecreditNotice[tagName] tagValueendendif msg.reply thenmsg.reply(debitNotice)elseSend(debitNotice)endSend(creditNotice)endelseif msg.reply thenmsg.reply({Action Transfer-Error,[Message-Id] msg.Id,Error Insufficient Balance!})elseSend({Target msg.From,Action Transfer-Error,[Message-Id] msg.Id,Error Insufficient Balance!})endend
end)// mint铸造、增发代币
Handlers.add(mint, Handlers.utils.hasMatchingTag(Action,Mint), function(msg)assert(type(msg.Quantity) string, Quantity is required!)assert(bint(0) bint(msg.Quantity), Quantity must be greater than zero!)if not Balances[ao.id] then Balances[ao.id] 0 endif msg.From ao.id thenBalances[msg.From] utils.add(Balances[msg.From], msg.Quantity)TotalSupply utils.add(TotalSupply, msg.Quantity)if msg.reply thenmsg.reply({Data Colors.gray .. Successfully minted .. Colors.blue .. msg.Quantity .. Colors.reset})elseSend({Target msg.From,Data Colors.gray .. Successfully minted .. Colors.blue .. msg.Quantity .. Colors.reset})endelseif msg.reply thenmsg.reply({Action Mint-Error,[Message-Id] msg.Id,Error Only the Process Id can mint new .. Ticker .. tokens!})elseSend({Target msg.From,Action Mint-Error,[Message-Id] msg.Id,Error Only the Process Id can mint new .. Ticker .. tokens!})endend
end)// totalSupply处理查询总供应量的请求
Handlers.add(totalSupply, Handlers.utils.hasMatchingTag(Action,Total-Supply), function(msg)assert(msg.From ~ ao.id, Cannot call Total-Supply from the same process!)if msg.reply thenmsg.reply({Action Total-Supply,Data TotalSupply,Ticker Ticker})elseSend({Target msg.From,Action Total-Supply,Data TotalSupply,Ticker Ticker})end
end)// burn销毁代币
Handlers.add(burn, Handlers.utils.hasMatchingTag(Action,Burn), function(msg)assert(type(msg.Tags.Quantity) string, Quantity is required!)assert(bint(msg.Tags.Quantity) bint(Balances[msg.From]), Quantity must be less than or equal to the current balance!)Balances[msg.From] utils.subtract(Balances[msg.From], msg.Tags.Quantity)TotalSupply utils.subtract(TotalSupply, msg.Tags.Quantity)if msg.reply thenmsg.reply({Data Colors.gray .. Successfully burned .. Colors.blue .. msg.Tags.Quantity .. Colors.reset})elseSend({Target msg.From, Data Colors.gray .. Successfully burned .. Colors.blue .. msg.Tags.Quantity .. Colors.reset })end
end)
这段合约实现了一个简单的token系统支持基本的token操作如查询余额、转账、铸造和销毁token。通过使用处理器模式代码结构清晰易于扩展。若要进一步提高代码的安全性和可读性可以考虑添加详细的注释和更多的错误处理机制。
4.2 使用golang调用token
package mainimport (github.com/liteseed/aogogithub.com/liteseed/goar/signergithub.com/liteseed/goar/taglog//aogo 库用于与 Arweave 的智能合约交互//goar 库用于处理钱包签名和消息标签
)func main() {walletPath : ./wallet.json// 从钱包路径创建签名器s, err : signer.FromPath(walletPath)if err ! nil {log.Fatalf(创建签名器失败%v, err)}// 初始化 AO 对象ao, err : aogo.New()if err ! nil {log.Fatalf(初始化 AO 对象失败%v, err)}// 定义目标合约 IDprocessPID : jysQej65l7KHRZi93csg0rvdmciJNL9hteM1N_yakpE // 合约 ID// 定义标签定义操作及操作者tags : []tag.Tag{{Name: Action, Value: Balance},{Name: Target, Value: Glj6gtx-NJNXTWOF9z9dN2aue3KyU5A_sxR71L1Cak8},}// 向目标合约发送消息messageID, err : ao.SendMessage(processPID, , tags, , s)if err ! nil {log.Fatalf(发送消息失败%v, err)}log.Println(成功发送消息消息 ID, messageID)res, err : ao.LoadResult(processPID, messageID)if err ! nil {log.Fatalf(读取消息失败%v, err)}log.Println(res.Messages)log.Println(res.Error)
}
这段代码展示了如何在 Arweave 网络上发送数据并与智能合约交互。通过创建签名器、定义标签、发送消息和读取结果。
4.3 获取消息信息
可以从API中获得消息信息
https://cu49.ao-testnet.xyz/result/zpPRT9ASUBrT1-OO2LRIfz3IeALW9HiSlHhk6QOmRP0?process-idjysQej65l7KHRZi93csg0rvdmciJNL9hteM1N_yakpEresult 后跟Message Idprocess-id则是我们的token合约ID
返回结果为
{Messages:[{Target:60vmK1FkO0f84yHggO5os6n3e_YnVF6O7V6IeX1vjaU,Data:0,Tags:[{name:Data-Protocol,value:ao},{name:Variant,value:ao.TN.1},{name:Type,value:Message},{name:From-Process,value:jysQej65l7KHRZi93csg0rvdmciJNL9hteM1N_yakpE},{name:From-Module,value:5l00H2S0RuPYe-V5GAI-1RgQEHFInSMr20E-3RNXJ_U},{name:Ref_,value:10},{name:Balance,value:0},{name:Account,value:60vmK1FkO0f84yHggO5os6n3e_YnVF6O7V6IeX1vjaU},{name:Ticker,value:PNTS}],Anchor:00000000000000000000000000000010}],Assignments:[],Spawns:[],Output:[],GasUsed:601453529}注所有发送的消息及返回的消息都会上链大概十分钟左右