2 个版本
使用旧的 Rust 2015
0.0.1 | 2018 年 11 月 8 日 |
---|---|
0.0.0 | 2018 年 8 月 27 日 |
#12 在 #wavelet
18KB
340 行
transaction-processor-rs
使用 Rust 编写 Wavelet 的交易处理器。
什么是交易处理器?
在 Wavelet 中,当接受有效交易时,它会应用于账本状态。交易处理器定义了交易对账本状态应有什么影响。
例如,如 builtin/money
中定义的,标记为 transfer
的交易,如果有效,应从发送者账户的余额中扣除 amount
PERLs,并将扣除的余额添加到 recipient
账户。
编写自己的交易处理器
每次应用交易时都会调用交易处理器。交易处理器的入口函数应有签名 (context: TransactionContext) -> ProcessResult<()>
。参数 context
包含交易的 标记 和 负载,其中 标记 用于其类型,而 负载 包含处理器定义的信息。在入口函数内部,您应将 context.tag
与您自己定义的标记进行匹配,并且只有在标记是您想要的时才执行您的逻辑。否则,什么也不做并返回 Err(ProcessError::Ignore)
。
编写完入口函数后,使用宏 processor_entry!(your_entry);
进行注册。交易处理器只能有一个入口函数。
让我们以内置的 money
处理器(处理 transfer
交易)为例。
首先,我们定义所有必要的序列化和反序列化数据结构
#[derive(Deserialize)]
pub struct Transfer {
recipient: String,
amount: u64,
}
#[derive(Serialize)]
pub struct ContractReason {
pub kind: String,
pub details: TransferReason,
}
#[derive(Serialize)]
pub struct TransferReason {
pub amount: u64,
pub sender: String,
}
然后是入口函数
// We name the entry as `handle_transaction`; Can change to whatever your want.
fn handle_transaction(context: TransactionContext) -> ProcessResult<()> {
// Match on the transaction tag.
match context.tag.as_str() {
"transfer" => {
// Read and decode the payload as type `Transfer`.
let payload: Transfer = context.read_payload()?;
// Load transaction sender.
// Currently, most information about the transaction is kept as immutable global state.
let sender = Account::sender();
// Load transaction recipient with `payload.recipient` as its ID.
let recipient = Account::load(&payload.recipient);
// Invoke the builtin `transfer` operation.
transaction_processor::transfer::transfer(&sender, &recipient, payload.amount)?;
// Build activation reason for the smart contract system.
let reason = transaction_processor::serde_json::to_vec(&ContractReason {
kind: "transfer".into(),
details: TransferReason {
amount: payload.amount,
sender: Account::sender_id(),
},
}).unwrap();
// If the recipient is a smart contract, activate it.
transaction_processor::contract::activate(&payload.recipient, &reason)?;
Ok(())
}
_ => Err(ProcessError::Ignore), // Ignore any transactions we don't understand.
}
}
注册入口
processor_entry!(handle_transaction);
构建
请确保您已安装带有 wasm32-unknown-unknown
目标的最新稳定 Rust 工具链。如果您尚未安装目标,请使用以下命令进行安装:
rustup target add wasm32-unknown-unknown
然后,在您的项目目录下运行
cargo build --release --target wasm32-unknown-unknown
贡献
我们在 Perlin 喜欢与开源社区互动,并且愿意接受问题和拉取请求。
对于所有代码贡献,请确保它们尽可能遵循以下指南
- 修复 Rust 编译器生成的所有警告,除非在某些非常特殊的情况下。
- 提交信息格式为
module_name: 将按下的内容 as 作为一句话。
这使得我们的维护者和其他人都能知道您希望解决的具体代码更改。 - 考虑向后兼容性。新方法是完全可以接受的,但例如更改现有公共 API 应仅在有充分理由的情况下进行。
如果您...
- 喜欢我们正在做的工作,
- 想要全职与我们合作,
- 或者对为开源项目工作并获得报酬感兴趣
... 我们在招聘。
为了吸引我们的注意,只需提交一个 PR 并开始贡献。
依赖项
~0.7–1.4MB
~33K SLoC