作者:Xiang|W3.Hitchhiker
修订:Evelyn|W3.Hitchhiker
(↑点击此链接框,打开文档)
SmartWeave 使用 AR 代币使开发人员能够使用 Javascript 构建所有类型的智能合约应用程序。
由于 SW 合约本身是在客户端更新的,为了获取合约的最新状态,客户端需要通过每次交互来找到其最新的有效状态。与使用ardb从 Arweave 获取交易等其他选项相比,可能会很慢。
SmartWeave 合约分为三部分:
为了评估合约状态,SmartWeave 协议客户端:
sha256(transactionId + blockHash)
. 完整的顺序是[ block_height, sha256(transactionId + blockHash) ]
.handler
功能上——评估合约的状态直到请求的区块高度。合约源就是代码本身,用 JavaScript 编写。这是将在客户端(执行者)上运行以更新状态并获取最新且有效的状态的合约。合约它定义了项目将是什么,以及您希望它做什么。
合约源永远不会改变,这可以保证用户使用的东西永远是真实的。
状态通常是写合约的第一件事,让我们编写一些简单的代码测试,每次调用increment
函数时都会增加调用者的余额。 caller
是与该合约源交互的钱包地址。
export function handle(state, action) {
const balances = state.balances;
const input = action.input;
const caller = action.caller;
if(input.function === 'increment') {
// If the caller already is a key of balances, increment, if not, set it to 1.
if(caller in balances) {
balances[caller]++;
} else {
balances[caller] = 1;
}
}
}
(该文件保存为first.js。)
所有 SmartWeave 合约都必须以函数(state,action){}
开头,因为这是执行程序调用的函数。其他所有内容都应该在该handle
函数中。
现在handle
本身很混乱,因为我们不知道state
和action
参数是什么。我们先解释一下这个action
。 动作参数 action
是在执行 SmartWeave 合约时发送的动作,每次你想要对 SW 合约进行更新时,你都需要发送输入交易,这通常包括函数名称input.function
和任何其他参数你需要和它一起发送。目前这种情况下,我们不需要发送任何其他内容,但例如我们可以发送input.qty
来指定我们想要增加余额的数量,这也需要在合约源代码中指定才能正常工作。请记住,这是由钱包所有者控制的,因此我们需要在接收用户数据时始终具备条件,以防止出现意外的情况。
动作参数也将调用者作为该对象的键。同样,调用者是运行该函数的人。这是唯一起作用的两个键:action
: input
and caller
.
状态是合约状态,它让用户知道你的合约的更新是什么,以及它在哪里,在执行的那一刻。 这个会随着时间的推移(在客户端)更新,而合约源永远不会改变。
当我们第一次创建合约时,我们还需要发送一个状态,也就是初始状态。
我们可以在我们的合约源中看到,状态是一个 balances
对象,其中包括钱包地址(caller
)作为键,并且每个调用者键都有一个数字作为其值。 在这个例子中,让我们为自己添加一些余额作为初始状态,状态是一个 JSON 对象:
{
"balances": {
"S2aewhZzchiyRsAisLAdZKudF6r9JlO_WDSGkaLGMZ4": 10000
}
}
(该文件保存为first.json)
这表明当第一个人去读我们的合约时,第一个状态是这个地址有 1,000 个该代币余额。
状态和合约源都必须是发送到 Arweave 的单独交易,并且都只部署一次。 之后,通过发送包含input
交易来更新状态。
在说执行者之前,我们先来看看应该如何处理合约源和初始状态。 这两个都只是普通的交易,但带有一些特殊的标签。 我们可以使用 SmartWeaveJS 作为 CLI 工具来部署这些合约。
首先安装smartweave包(建议使用最新的稳定node版本):
npm install -g smartweave
然后可以通过以下指令部署合约:
smartweave create [SRC LOCATION] [INITIAL STATE FILE] --key-file [YOUR KEYFILE]
SRC LOCATION 是指的合约源,INITIAL STATE FILE是初始状态文件,YOUR KEYFILE 是指生成钱包时的keyfile文件。参考下图配置:
交易ID: _PMfm736sE_pqPS-FQvYgkwqbm-8VJBPGlQRTm89ZBE
读取合约状态:
smartweave read [CONTRACT TXID]
这样就成功部署了您的第一个 SmartWeave 合约。
与合约交互(写合约):
smartweave write [CONTRACT TXID] --key-file [YOUR KEYFILE] \
--input "[CONTRACT INPUT STRING HERE]"
如果要测试不写入主网,与测试网络交互,请将 --dry-run
附加到 --interact
调用中.
但由于我们是来学习的,所以也可以了解下使用 ArweaveJS 手动创建这些交易。参考以下代码:
import Arweave from 'arweave';
const arweave = Arweave.init({
host: 'arweave.net',
protocol: 'https',
port: 443
});
async function createContract() {
// Let's first create the contract transaction.
const contractTx = await arweave.createTransaction({ data: contractSource }, wallet);
contractTx.addTag('App-Name', 'SmartWeaveContractSource');
contractTx.addTag('App-Version', '0.3.0');
contractTx.addTag('Content-Type', 'application/javascript');
// Sign
await arweave.transactions.sign(contractTx, wallet);
// Let's keep the ID, it will be used in the state transaction.
const contractSourceTxId = contractTx.id;
// Deploy the contract source
await arweave.transactions.post(contractTx);
// Now, let's create the Initial State transaction
const initialStateTx = await arweave.createTransaction({ data: initialState }, wallet);
initialState.addTag('App-Name', 'SmartWeaveContract');
initialState.addTag('App-Version', '0.3.0');
initialState.addTag('Contract-Src', contractSourceTxId);
initialState.addTag('Content-Type', 'application/json');
// Sign
await arweave.transactions.sign(initialState, wallet);
const initialStateTxId = initialState.id;
// Deploy
await arweave.transactions.post(initialState);
}
createContract()
类似于以太坊的remix,AR也有自己的网页端部署工具
(↓点击此链接框,打开网页)
点击左下方登陆钱包,这里可以下载AR的钱包插件ArConnect进行连接,如果没有,可以先去下载。
进入后可以使用studio自带的代币合约部署,然后点击坐上的火箭图标进行部署。
此时需要选择部署的钱包,方法,部署网络,合约源,合约初始状态等。
部署成功后会获取交易ID
TX: YdVWeK5ftuIBmCTEbNQCwSFT13KZIJsuJ6OaVqjFvoY
这样就成功部署token-pst合约了。
与合约交互,读取合约数据:
与合约交互,写合约数据: