合约(Contract)

Contract是部署到区块链的代码的抽象。

合约可以被用来发送交易,将交易数据作为参数运行代码。

创建实例

new ethers.Contract( address , abi , signerOrProvider )
contract.attach( addressOrName ) 合约(Contract)

返回一个附加到新地址的Contract新实例。 如果网络上有多个类似或相同的合约副本,并且您希望与它们中的每一个进行交互,那么这是非常有用的。

contract.connect( providerOrSigner ) 合约(Contract)

返回合约的一个新实例,但需要连接到providerOrSigner

通过传入一个Provider,这将返回一个低级的合约实例,它只有只读访问的权限(即常量调用)。

通过传入一个Signer,这将返回一个代表该签名人(signer)的合约实例。

属性

contract.address string< 地址(Address) >

这是构建合约时使用的地址(或ENS名称)。

contract.resolvedAddress string< 地址(Address) >

这是一个合约对象将解析合约地址的promise。 如果一个地址(Address)被提供给构造函数,它将解析成这个地址; 如果提供的是ENS名称,这将解析成对应的地址。

contract.deployTransaction TransactionResponse

如果Contract是ContractFactory部署后返回的对象, 那么contract.deployTransaction返回的数据就是部署这个合约的交易信息(transaction)。

contract.interface Interface

这是作为Interface接口的ABI。

contract.provider Provider

如果构造函数使用的是provider生成的contract合约对象,那么这个结果就是这个provider。 如果使用的是具有Provider的signer,那么这个结果就是provider。

contract.signer Signer

如果构造函数使用的是signer生成的contract合约对象,那么这个结果就是这个signer。

方法

contract.deployed( ) Promise< 合约(Contract) >
Contract.isIndexed( value ) boolean

事件(Events)

contract.queryFilter( event [ , fromBlockOrBlockHash [ , toBlock ] ) Promise< Array< Event > >

返回与event匹配的事件。

contract.listenerCount( [ event ] ) number

返回订阅该event的监听器数量。如果没有提供event,则返回所有事件的总数。

contract.listeners( event ) Array< Listener >

返回订阅该event的监听器列表。

contract.off( event , listener ) this

监听器取消订阅event事件。

contract.on( event , listener ) this

监听event事件,当事件发生时,会调用listener函数。

contract.once( event , listener ) this

监听event事件,当事件发生时,仅调用一次listener函数。

contract.removeAllListeners( [ event ] ) this

取消所有订阅event事件的监听器。如果未提供event事件,则取消订阅所有事件的监听。

元类(Meta-Class)

元类是在运行时确定其所有属性的类。Contract对象使用合约的ABI来确定可使用方法(methods), 因此下面的部分将描述用一些属性,来与在合约构造函数期间交互的通用方法。

只读的方法 (常量; 如 view 或 pure)

常量方法是只读的,针对当前区块链状态计算少量EVM代码,并可以通过请求单个节点来计算,该节点会返回一个结果。 因此,它是免费的,不需要任何以太币,但不能更改区块链状态。

contract.METHOD_NAME( ...args [ , overrides ] ) Promise< any >

结果的类型取决于ABI。如果方法返回单个值,则将直接返回该值,否则将返回一个Result对象,其中包含每个位置可用的参数, 如果参数被命名,那么就按照命名后的值去执行。

如果返回的值匹配JavaScript中的类型值,如strings字符串类型 和 booleans布尔类型,那么返回的值类型就直接是JavaScript中的类型值。

但对于numbers类型,如果类型在JavaScript的安全范围内(即小于53位,如int24uint488),则使用标准的JavaScript number类型。 否则返回大数(BigNumber)类型。

对于字节bytes类型(包括固定长度和动态),将返回一个DataHexString

如果call reverts(或runs out of gas),将抛出一个CALL_EXCEPTION,其中包括:

  • error.address - 合约地址
  • error.args - 合约方法中传入的参数
  • error.transaction - 交易

只读方法的overrides对象可以包括以下任何一个:

  • overrides.from - 代码执行期间使用的msg.sender (或 CALLER)
  • overrides.value - 代码执行期间使用的msg.value (或 CALLVALUE)
  • overrides.gasPrice - 每个gas的价格(理论上);因为没有交易,所以不会收取任何费用,但EVM仍然需要向tx.gasprice(或GASPRICE)传递value值; 大多数开发人员不需要这样做

  • overrides.gasLimit - 在执行代码期间允许节点使用的gas数量(理论上);因为没有交易,所以不会有任何费用,但EVM仍然估计gas总数量,因此会向gasleft (或 GAS) 传递这些值。

  • overrides.blockTag - 一个用来模拟在哪里执行的块标签,可以用于假设性历史分析;注意,许多后端不支持这一点,或者可能需要付费访问,因为节点数据库存储和处理需求费用要高得多

contract.functions.METHOD_NAME( ...args [ , overrides ] ) Promise< Result >

结果将始终是Result,即使只有一个返回值类型。

这简化了期望使用合约(Contract)对象的框架,因为它们不需要检查返回类型来展开简化函数。

此方法的另一个用途是用于错误恢复。例如,如果一个函数的结果是一个无效的UTF-8字符串,使用上述元类函数的普通调用将抛出一个异常。 这允许使用Result access error来访问低级字节以及错误的原因,从而允许使用另一种UTF-8错误策略。

大多数开发人员不需要这样做。

overrides与上面的只读操作相同。

Write Methods (non-constant)

非常量方法要求签名一笔交易,并需要向矿工支付费用。这个交易将由整个网络上的所有节点以及矿工进行验证, 矿工会根据当前状态执行,接着在区块链计算新状态。

它不能返回结果。如果需要一个结果,那么应该使用Solidity事件(或EVM日志)对其进行记录,然后可以从交易收据中查询该事件。

contract.METHOD_NAME( ...args [ , overrides ] ) Promise< TransactionResponse >

交易被发送到网络后,返回交易的TransactionResponseContract合约对象需要signer。

重写方法的overrides对象可以是以下任何一个:

  • overrides.gasPrice - 每个gas的价格
  • overrides.gasLimit - 该笔交易允许使用的gas的最大数量,未被使用的gas按照gasPrice退还
  • overrides.value - 调用中转账的ether (wei格式)数量
  • overrides.nonce - Signer使用的nonce值

如果返回的TransactionResponse使用了wait()方法,那么在收据上将会有额外的属性:

  • receipt.events - 带有附加属性的日志数组(如果ABI包含事件的描述)
  • receipt.events[n].args - 解析后的参数
  • receipt.events[n].decode - 可以用来解析日志主题(topics)和数据的方法(用于计算args)
  • receipt.events[n].event - 事件的名称
  • receipt.events[n].eventSignature - 这个事件完整的签名
  • receipt.removeListener() - 用于移除触发此事件的监听器的方法
  • receipt.getBlock() - 返回发生触发此事件的Block
  • receipt.getTransaction() - 返回发生触发此事件的Transaction
  • receipt.getTransactionReceipt() - 返回发生触发此事件的Transaction Receipt

Write Methods Analysis

在不实际执行的情况下,有几个选项可以分析write method的属性和结果。

contract.estimateGas.METHOD_NAME( ...args [ , overrides ] ) Promise< 大数(BigNumber) >

返回使用 argsoverrides执行METHOD_NAME所需的gas的估计单位。

overrides与上面针对只读或写方法的overrides相同,具体取决于 METHOD_NAME调用的类型。

contract.populateTransaction.METHOD_NAME( ...args [ , overrides ] ) Promise< UnsignedTx >

返回一个未签名交易(UnsignedTransaction),它表示需要签名并提交给网络的交易,以执行带有argsoverridesMETHOD_NAME

overrides与上面针对只读或写方法的overrides相同,具体取决于 METHOD_NAME调用的类型。

contract.callStatic.METHOD_NAME( ...args [ , overrides ] ) Promise< any >

比起执行交易状态更改,更可能是会要求节点尝试调用不进行状态的更改并返回结果。

这实际上并不改变任何状态,而是免费的。在某些情况下,这可用于确定交易是失败还是成功。

otherwise函数与Read-Only Method相同。

overrides与上面的只读操作相同。

Event Filters

事件过滤器由主题(topics)组成,这些主题是Bloom Filter中记录的值,允许对匹配过滤器的条目进行有效搜索。

contract.filters.EVENT_NAME( ...args ) Filter

返回EVENT_NAME的过滤器,可以通过增加其他约束进行过滤。

只有indexed索引的事件参数可以被过滤。如果参数为空(或未提供),则该字段中的任何值都匹配。