合约抽象封装
Truffle 提供合约抽象,用于与合约交互。跳到 api 部分,查看合约方法列表。
用法
要获取合约抽象,您可以要求它使用对象中的合约名称。在控制台外部,这是迁移文件、测试和执行脚本中可用的对象。 您需要按以下方式签订合同:artifacts
const MyContract = artifacts.require(“MyContract”);
您也可以在开发者控制台中获取一个。您的合约类型可在此处找到,您需要做的就是使用 、 或 方法。at``deployed``new
truffle(development)> const myContract = await MyContract.deployed();
您现在可以访问 上的以下功能以及许多其他功能:MyContract
-
at()
:在特定地址创建一个代表您的合约的实例。MyContract
-
deployed()
:创建一个实例,该实例表示由 管理的默认地址。MyContract``MyContract
-
new()
:将此协定的新版本部署到网络,获取代表新部署实例的实例。MyContract
每个实例都绑定到以太坊网络上的特定地址,并且每个实例都有从 Javascript 函数到合约函数的 1 对 1 映射。例如,如果你的 Solidity 合约定义了一个函数 (solidity),那么你可以像这样在网络上执行该函数:someFunction(uint value) {}
let deployed;
MyContract.deployed()
.then((instance) => {
deployed = instance;
return deployed.someFunction(5);
}).then((result) => {
// Do something with the result or continue with more transactions.
});
您还可以使用 async/await 语法,该语法通常不那么冗长。 在本文档的其余部分,我们将使用 async/await,但您也可以使用 promise 与合约方法进行接口。
const deployed = await MyContract.deployed();
const result = await deployed.someFunction(5);
// Do something with the result or continue with more transactions.
请参阅处理事务结果部分,了解有关从进行事务中获得的结果对象的详细信息。
协定方法和事件具有 EventEmitter 接口。因此,您可以设置如下所示的处理程序:
const example = await artifacts.require(“Example”).deployed();
example
.setValue(45)
.on(‘transactionHash’, hash => {})
.on(‘receipt’, receipt => {})
.on(‘error’, error => {})
.on(‘confirmation’, (num, receipt) => {})
.then(receipt => {});
example
.ExampleEvent()
.on(‘data’, event => … etc … )
example
.ExampleEvent()
.once(‘data’, event => … etc … )
应用程序接口
您需要注意两个 API。一个是静态合约抽象 API,另一个是合约实例 API。抽象 API 是一组存在于所有合约抽象的函数,这些函数存在于抽象本身(即 )。相比之下,实例 API 是可用于合约实例的 API,即表示网络上特定合约的抽象,并且该 API 是根据 Solidity 源文件中可用的函数动态创建的。MyContract.at()
合约抽象 API
在上面的例子中,每个合约抽象都具有以下有用的功能:MyContract
MyContract.new([arg1, arg2, ...], [tx params])
此函数采用合约所需的任何构造器参数,并将合约的新实例部署到网络。有一个可选的最后一个参数,您可以使用它来传递交易参数,包括来自地址的交易、gas 限制和 gas 价格。此函数返回一个 Promise,该 Promise 解析为新部署地址的合约抽象的新实例。
MyContract.at(address)
此函数创建在传入地址处表示协定的协定抽象的新实例。返回一个“thenable”对象(还不是用于向后兼容的实际 Promise)。在确保代码存在于指定地址后解析为合约抽象实例。
MyContract.deployed()
创建在协定部署地址处表示协定的协定抽象实例。部署的地址是 truffle-contract 的一个特殊值,设置后,它会在内部保存地址,以便可以从正在使用的给定以太坊网络推断出部署的地址。这允许您编写引用特定已部署协定的代码,而无需自己管理这些地址。Like ,是可实现的,并且在确保代码存在于该位置并且该地址存在于正在使用的网络上后,将解析为表示已部署协定的协定抽象实例。at()``deployed()
MyContract.link(instance)
将合约抽象实例表示的库链接到 MyContract。必须首先部署库并设置其部署的地址。名称和部署的地址将从合约抽象实例中推断出来。使用这种形式时,MyContract 将使用链接库的所有事件,并能够报告这些事件在事务结果期间发生。MyContract.link()
库可以多次链接,并将覆盖其以前的链接。
注意:此方法还有另外两种形式,但建议使用此形式。
MyContract.link(name, address)
将具有特定名称和地址的库链接到 MyContract。不会使用此表单使用库的事件。
MyContract.link(object)
将 Object 表示的多个库链接到 MyContract。键必须是表示库名称的字符串,值必须是表示地址的字符串。如上所述,库的事件不会使用此表单。
MyContract.networks()
查看此协定抽象已设置为表示的网络 ID 列表。
MyContract.setProvider(provider)
设置此合约抽象将用于进行交易的 web3 提供者。
MyContract.setNetwork(network_id)
设置 MyContract 当前表示的网络。
MyContract.hasNetwork(network_id)
返回一个布尔值,表示是否将此协定抽象设置为表示特定网络。
MyContract.defaults([new_defaults])
Get 和 (可选)为从此抽象创建的所有实例设置事务默认值。如果调用时没有任何参数,它只会返回一个表示当前默认值的 Object。如果传递了 Object,这将设置新的默认值。可以设置的默认事务值示例为:
MyContract.defaults({
from: …,
gas: …,
gasPrice: …,
value: …
})
例如,当您有一个合约抽象打算表示一个用户(即一个地址)时,设置默认地址很有用。from
MyContract.clone(network_id)
克隆一个合约抽象,以获得另一个对象,该对象管理相同的合约工件,但使用不同的 .如果您想在不同的网络上管理相同的合同,这将非常有用。使用此功能时,不要忘记设置正确的提供程序。network_id
const MyOtherContract = MyContract.clone(1337);
MyContract.numberFormat = number_type
可以设置此属性以选择抽象方法返回的数字格式。默认行为是返回 BN。
// Choices are: `[“BigNumber”, “BN”, “String”].
const Example = artifacts.require(‘Example’);
Example.numberFormat = ‘BigNumber’;
MyContract.timeout(block_timeout)
此方法允许您设置交易的区块超时。从此抽象创建的合约实例将具有指定的事务块超时。这意味着,如果交易没有立即被挖掘,它将重试指定数量的区块。
MyContract.autoGas = <boolean>
如果将其设置为 true,则从此抽象创建的实例将使用并应用 gas 乘数来确定要包含在事务中的 gas 量。其默认值为 。请参见 gasMultiplier。web3.eth.estimateGas``true
MyContract.gasMultiplier(gas_multiplier)
这是启用时用于确定要包含在交易中的 gas 量的值。气体是通过使用气体并将其乘以气体乘数来计算的。默认值为 。autoGas``web3.eth.estimateGas``1.25
合约实例 API
每个合约实例根据源 Solidity 合约的不同而不同,API 是动态创建的。在本文档中,我们使用以下 Solidity 源代码:
contract MyContract {
uint public value;
event ValueSet(uint val);
function setValue(uint val) {
value = val;
emit ValueSet(value);
}
function getValue() constant returns (uint) {
return value;
}
}
从 Javascript 的角度来看,这个合约有三个函数:、 和 。这是因为它是公共的,并自动为其创建一个 getter 函数。setValue``getValue``value``value
通过合约功能进行交易
当我们调用 时,这会创建一个事务。来自 Javascript:setValue()
const result = await instance.setValue(5);
// result object contains import information about the transaction
console.log(“Value was set to”, result.logs[0].args.val);
返回的结果对象如下所示:
{
tx: “0x6cb0bbb6466b342ed7bc4a9816f1da8b92db1ccf197c3f91914fc2c721072ebd”,
receipt: {
// The return value from web3.eth.getTransactionReceipt(hash)
// See https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethgettransactionreceipt
},
logs: [
{ logIndex: 0,
transactionIndex: 0,
transactionHash: ‘0x728b4d1983cd00d93ae00b7adf76f78c1b32d922de636ead42e93f70cf58cdc9’,
blockHash: ‘0xdce5e6c580267c9bf1d82bf0a167fa60509ef9fc520b8619d8183a8373a42035’,
blockNumber: 19,
address: ‘0x035b8A9e427d93D178E2D22d600B779717696831’,
type: ‘mined’,
id: ‘log_70be22b0’,
event: ‘Transfer’,
args:
Result {
‘0’: ‘0x7FEb9FAA5aED0FD547Ccc70f00C19dDe95ea54d4’,
‘1’: ‘0x7FEb9FAA5aED0FD547Ccc70f00C19dDe95ea54d4’,
‘2’: <BN: 1>,
length: 3,
_from: ‘0x7FEb9FAA5aED0FD547Ccc70f00C19dDe95ea54d4’,
_to: ‘0x7FEb9FAA5aED0FD547Ccc70f00C19dDe95ea54d4’,
_value: <BN: 1>
}
}
],
}
请注意,如果事务中执行的函数具有返回值,则不会得到该值 返回此结果中的值。您必须改用事件(如 )并查找结果 在数组中。ValueSet``logs
显式发出调用而不是事务
我们可以在不创建事务的情况下调用,方法是显式使用:setValue()``.call
const value = await instance.setValue.call(5);
在这种情况下,这并不是很有用,因为设置了东西,并且由于我们没有创建事务,因此不会保存我们传递的值。setValue()
调用 getter
但是,我们可以使用 ,使用 来_获取_值。调用始终是免费的,并且不收取任何以太币,因此它们非常适合调用从区块链读取数据的函数:getValue()``.call()
const value = await instance.getValue.call();
// value reprsents the value
storage object in the solidity contract
// since the contract returns that value.
然而,更有用的是,当一个函数被标记为 时,我们_甚至不需要_使用,因为会自动知道该函数只能通过调用进行交互:.call``constant``truffle-contract
const value = await instance.getValue();
// val reprsents the value
storage object in the solidity contract
// since the contract returns that value.
处理交易结果
当您进行交易时,您将获得一个对象,该对象为您提供有关交易的大量信息。您将获得事务 ()、解码事件(也称为日志;)和事务收据 ()。在下面的示例中,你将收到该事件,因为您使用以下函数触发了该事件:result``result.tx``result.logs``result.receipt``ValueSet()``setValue()
const result = await instance.setValue(5);
// result.tx => transaction hash, string
// result.logs => array of trigger events (1 item in this case)
// result.receipt => receipt object
发送以太币/触发回退功能
您可以通过向此函数发送事务来触发回退函数:
const result = instance.sendTransaction({…});
// Same result object as above.
这与所有可用的合约实例函数一样被承诺,并且具有与没有回调相同的 API。系统将自动为您填写该值。web3.eth.sendTransaction``to
如果您只想将以太币发送到合约,可以使用速记:
const result = await instance.send(web3.toWei(1, “ether”));
// Same result object as above.
估算气体使用量
运行此函数以估算气体使用量:
const result = instance.setValue.estimateGas(5);
// result => estimated gas for this transaction