W3Schools



我想得到合同内部交易,如:HTTPS://ether scan.IO/address/0许多654不道德32非常99471455哦86从2哦7发7的7不6437哦9179#internal TX

我正在使用web3 API。有什么办法吗?它们出现在区块链中的哪个位置?

transactionsweb3jsinternal-transactions
7个回答
36

目前没有任何方法可以使用web3 API执行此操作。内部交易,尽管名称(不是黄皮书的一部分;它是人们已经确定的惯例)不是实际交易,并且不直接包含在区块链中;它们是通过执行合同启动的价值转移。

因此,它们不会明确地存储在任何地方:它们是在区块链状态下运行有关交易的效果。像etherscan这样的区块链探索者可以通过运行带有检测EVM的修改节点来获取它们,这些EVM记录了作为事务执行的一部分发生的所有值传输,并单独存储它们。


19

在以太坊协议中,只有事务和消息调用。事务是一种消息调用。

事务可以执行其他消息调用,但这些不是事务(即使区块链资源管理器可能将它们不准确地标记为“内部事务”)。这些(内部)消息调用 are not published on the blockchain. To find the 内部电话, the transaction needs to be processed through the EVM (for example, HTTPS://GitHub.com/ether EU MJ是/ether EU MJ是-VM).

尝试说明,aJavascript中的事务看起来像:

{
  from: ...,
  to: "C1",
  value: ...,
  gas: ...,
  data: ...,
  gasPrice: ...,
  nonce: ...
}

这是您将在区块链上看到的内容。内部电话 are the effects of taking the data part, feeding it to the contract C1, and executing the Ethereum Virtual Machine. The data is what tells C1 that it should call another contract C2: there is no separate {from:C1, to:C2,...} object on the blockchain that's needed.

data is encoded according to an ABI表示应该调用哪个函数以及参数是什么。

注意: With @Nick's answer, all value transfers are a message call. But not all message calls are value transfers. A value transfer is when a contract is simply paid some Ether/wei (data is zero), but contracts can call each other without paying each other (data is non-zero, value is zero).


3

有了web3 + geth,你可能无法做到这一点,正如@Nick已经说过的那样。但根据Parity的1.1版本公告, you could do it with it if you switch to this client. Quoting:

用于跟踪,跟踪和检查所有内容的新JSONRPC API   消息调用和余额转移,包括那些发生的消息   “内部交易”;

但是还没有测试过。


10

幸运的是,Geth EVM拥有完成这项工作的新工具。可以将debug_traceTransaction与RPC API一起使用。

在NodeJS中:

var web3 = require('web3').web3;
web3.currentProvider.sendAsync({
    method: "debug_traceTransaction",
    params: ['0x3fac854179691e377fc1aa180b71a4033b6bb3bde2a7ef00bc8e78f849ad356e', {}],
    jsonrpc: "2.0",
    id: "2"
}, function (err, result) {
    ...
});

然后,您需要'CREATE','CALL','CALLCODE'和'DELEGATECALL'操作码并跟踪堆栈。你可以阅读尼克约翰逊 detailed explanation: 检测EVM

如果我最终实现它,我将用代码写一篇完整的文章。


2

随着Parity的最新版本(测试1.8.3) it is also possible. The RPC method is trace_replayTransaction. The corresponding code is something like

web3.currentProvider.sendAsync({
    method: "trace_replayTransaction",
    params: [desiredTransactionHash, ['trace']],
    jsonrpc: "2.0",
    id: "1"
}, function (err, out) {
    console.log(out);
}

文档 is at the parity github repository.


0

您可以使用callTracer introduced in geth 1.8 HTTPS://GitHub.com/ether EU M/go-ether EU M/pull/15516

$ nc -U /work/temp/rinkeby/geth.ipc
{"id": 1, "method": "debug_subscribe", "params": ["traceChain", "0x0", "0xffff", {"tracer": "callTracer"}]}

API将为每个非空块流回一个IPC通知。一个例外是最后一个块,它会 即使为空也要报告,以便用户知道流已完成。

{"jsonrpc":"2.0","id":1,"result":"0xe1deecc4b399e5fd2b2a8abbbc4624e2"}
{"jsonrpc":"2.0","method":"debug_subscription","params":{"subscription":"0xe1deecc4b399e5fd2b2a8abbbc4624e2","result":{"block":"0x37","hash":"0xdb16f0d4465f2fd79f10ba539b169404a3e026db1be082e7fd6071b4c5f37db7","traces":[{"from":"0x31b98d14007bdee637298086988a0bbd31184523","gas":"0x0","gasUsed":"0x0","input":"0x","output":"0x","time":"1.077µs","to":"0x2ed530faddb7349c1efdbf4410db2de835a004e4","type":"CALL","value":"0xde0b6b3a7640000"}]}}}
{"jsonrpc":"2.0","method":"debug_subscription","params":{"subscription":"0xe1deecc4b399e5fd2b2a8abbbc4624e2","result":{"block":"0xf43","hash":"0xacb74aa08838896ad60319bce6e07c92edb2f5253080eb3883549ed8f57ea679","traces":[{"from":"0x31b98d14007bdee637298086988a0bbd31184523","gas":"0x0","gasUsed":"0x0","input":"0x","output":"0x","time":"1.568µs","to":"0xbedcf417ff2752d996d2ade98b97a6f0bef4beb9","type":"CALL","value":"0xde0b6b3a7640000"}]}}}
{"jsonrpc":"2.0","method":"debug_subscription","params":{"subscription":"0xe1deecc4b399e5fd2b2a8abbbc4624e2","result":{"block":"0xf47","hash":"0xea841221179e37ca9cc23424b64201d8805df327c3296a513e9f1fe6faa5ffb3","traces":[{"from":"0xbedcf417ff2752d996d2ade98b97a6f0bef4beb9","gas":"0x4687a0","gasUsed":"0x12e0d","input":"0x6060604052341561000c57fe5b5b6101828061001c6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063230925601461003b575bfe5b341561004357fe5b61008360048080356000191690602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506100c5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600185858585604051806000526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff1681526020018360001916600019168152602001826000191660001916815260200194505050505060206040516020810390808403906000866161da5a03f1151561014257fe5b50506020604051035190505b9493505050505600a165627a7a7230582054abc8e7b2d8ea0972823aa9f0df23ecb80ca0b58be9f31b7348d411aaf585be0029","output":"0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063230925601461003b575bfe5b341561004357fe5b61008360048080356000191690602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506100c5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600185858585604051806000526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff1681526020018360001916600019168152602001826000191660001916815260200194505050505060206040516020810390808403906000866161da5a03f1151561014257fe5b50506020604051035190505b9493505050505600a165627a7a7230582054abc8e7b2d8ea0972823aa9f0df23ecb80ca0b58be9f31b7348d411aaf585be0029","time":"658.529µs","to":"0x5481c0fe170641bd2e0ff7f04161871829c1902d","type":"CREATE","value":"0x0"}]}}}
{"jsonrpc":"2.0","method":"debug_subscription","params":{"subscription":"0xe1deecc4b399e5fd2b2a8abbbc4624e2","result":{"block":"0xfff","hash":"0x254ccbc40eeeb183d8da11cf4908529f45d813ef8eefd0fbf8a024317561ac6b"}}}

单个块跟踪在事务中是并发的(仅限于num核心),也可以产生链 在块中跟踪并发(仅限于num核心)。


1

要获取有关内部事务的信息,可以使用debug_traceTransaction 该方法将返回事务的完整跟踪。通过每个步骤的操作码和参数,您可以获得所需的信息。

有两个主要问题: 1.确定操作码的工作原理,例如,并不总是CALL导致内部事务 2.如果跟踪中有大量步骤,则响应可能不适合缓冲区

第二个问题可以通过将第二个参数传递给处理geth侧步骤的方法来解决。更多详情可在这找到 -HTTPS://GitHub.com/ether EU M/go-ether EU M/wiki/management-APIs#debug_trace transaction

可以在这里找到如何处理操作码的逻辑HTTPS://GitHub.com/arachnid/ether query/blob/master/ether query/trace.go#l102 (for go implementation) or here HTTPS://GitHub.com/特特32/ether scanner/blob/master/trace step function.就是 (for nodejs implementation)