交易请求提供了提交交易和与区块链交互的基础。
在 Fuel 中,我们有以下类型的交易:
SDK 提供了处理脚本和创建交易的类助手:ScriptTransactionRequest
和 CreateTransactionRequest
。
注意: 铸币交易只能由区块生产者创建,并且在区块创建之外没有任何用途。因此,SDK 仅提供了解码铸币交易的功能。
要创建交易请求,您首先必须实例化 ScriptTransactionRequest
或 CreateTransactionRequest
中的一个。
ScriptTransactionRequest
用于脚本交易,允许您在链上执行字节码以执行任务或任务链。在 SDK 中,它们可以这样创建:
// #import { ScriptTransactionRequest };
// Instantiate the transaction request using a ScriptTransactionRequest
const transactionRequest = new ScriptTransactionRequest({
script: scriptBytecode,
});
// Set the script main function arguments (can also be passed in the class constructor)
transactionRequest.setData(scriptAbi, scriptMainFunctionArguments);
CreateTransactionRequest
用于创建交易,这些交易会在区块链上创建一个新的合约。
// #import { CreateTransactionRequest };
// Instantiate the transaction request using a CreateTransactionRequest
const transactionRequest = new CreateTransactionRequest({
witnesses: [contractByteCode],
});
注意: 我们建议您使用
ContractFactory
来部署合约,因为这将为您塑造创建交易请求。有关此信息,请参阅合约部署指南 。
一旦实例化了交易请求,就可以通过设置交易参数和策略来修改它。这可以通过直接修改交易请求对象手动完成,也可以通过上述类上可用的辅助方法完成。
资源填充了交易请求的输入和输出。这可以采取硬币、消息或合约的形式。SDK 提供了一系列处理资源的方法。以下将详细说明如何将硬币和消息添加到交易请求中。
// #import { ScriptTransactionRequest };
// Fetch the base asset ID
baseAssetId = provider.getBaseAssetId();
// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
script: scriptBytecode,
});
// Adding resources (coins or messages)
transactionRequest.addResources(resources);
transactionRequest.addResource(resource);
// Adding coin inputs and outputs (including transfer to recipient)
transactionRequest.addCoinInput(coin);
transactionRequest.addCoinOutput(recipientAddress, 1000, baseAssetId);
// Adding message inputs
transactionRequest.addMessageInput(message);
脚本可以在链上执行多个操作,因此您可能希望链式调用合约。为此,您需要将合约添加到交易请求中。可以像这样添加:
// #import { ScriptTransactionRequest };
// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
script: scriptBytecode,
});
// Add the contract input and output using the contract ID
transactionRequest.addContractInputAndOutput(contractId);
断言用于定义执行交易的条件。因此,您可能希望向交易请求添加断言以解锁由脚本使用的资金。可以像这样添加:
// #import { ScriptTransactionRequest, Predicate };
// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
script: scriptBytecode,
});
// Instantiate the predicate and pass valid input data to validate
// the predicate and unlock the funds
const predicate = new Predicate({
bytecode: predicateBytecode,
abi: predicateAbi,
inputData: dataToValidatePredicate,
provider,
});
const predicateCoins = await predicate.getResourcesToSpend([
{ amount: 2000, assetId: baseAssetId },
]);
// Add the predicate input and resources
transactionRequest.addResources(predicateCoins);
注意: 有关断言的更多信息,包括有关如何配置、资助和使用它们解锁资金的信息,请参阅断言指南 。
SDK 提供了一种直接修改交易请求的见证人的方法,也可以通过传递账户来完成。这将使用账户的私钥对交易请求进行签名。以下将详细说明如何向交易请求添加见证人:
// #import { ScriptTransactionRequest, Account, WalletUnlocked };
// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
script: scriptBytecode,
});
// Add a witness directly
transactionRequest.addWitness(witness);
// Add a witness using an account
const account: Account = WalletUnlocked.generate({ provider });
await transactionRequest.addAccountWitnesses(account);
在交易请求中添加多个见证人的更复杂示例可以在多签者指南 中看到,该指南验证脚本内的签名。
注意: 一旦调用了
addAccountWitnesses
,对交易请求的任何其他修改都会使签名失效,因为交易 ID 会发生变化。因此,建议在最后添加见证人。
交易 ID 是整个交易请求的 SHA-256 哈希。这对于在链上跟踪交易非常有用。要获取交易 ID,可以使用以下方法:
// #import { ScriptTransactionRequest };
// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
script: scriptBytecode,
});
// Get the chain ID
const chainId = provider.getChainId();
// Get the transaction ID using the Chain ID
const transactionId = transactionRequest.getTransactionId(chainId);
// TX ID: 0x420f6...
注意: 对交易请求进行的任何更改都会改变交易 ID。因此,应仅在进行所有修改后获取交易 ID。