Quiero atravesar la cadena de bloques de Ethereum, recopilar todas las instancias de contratos y contar con qué frecuencia se ha instanciado qué bytecode.
Como resultado quiero tener un mapa conkey:hash(bytecode) -> value:instanceCount
Si desea saber por qué lo estoy haciendo, lea EIP 911: Reduzca los costos de gas para implementar código de bytes en tiempo de ejecución copiando bytecodeHash de un contrato existente
Hasta ahora, tengo las siguientes ideas de cómo podría hacerse:
Idea 1 Use web3 para recopilar todas las transacciones con 0x0 como destino, obtenga la dirección del contrato del recibo, obtenga el código de este contrato, cuéntelo en el mapa. [P] : ¿cómo recopilar las instancias que ocurren dentro de los contratos (-> new
)?
Idea 2 Para cada bloque, obtenga el hash raíz del estado, cargue el trie correspondiente de la base de datos (leveldb/geth), recorra el árbol, recopile todas las cuentas, si la cuenta aún no se ha procesado, tome el código hash y aumente el conteo, muévase al bloque siguiente. [P] : atravesar el trie completo bloque por bloque es muy probablemente ineficiente. ¿Hay alguna manera de atravesar solo los caminos que cambiaron desde el último bloque?
Idea 3 Atraviese el trie de estado del último bloque únicamente y cuente las redundancias de código de bytes como se describe en 2. Esto simplifica la implementación, pero no se consideran los datos históricos.
[P] : ¿Alguna otra idea?
EDITAR : puede encontrar el contador de duplicación de código implementado en JavaScript en mi GitHub Repo -> https://github.com/ivica7/eth-chain-stats-collector
¡Idea interesante!
[P]: ¿cómo recopilar las instanciaciones que suceden dentro de los contratos (-> nuevo)?
Una opción es inspeccionar los rastros de transacciones. Geth proporciona la API de traceTransaction https://github.com/ethereum/go-ethereum/wiki/Management-APIs#debug_tracetransaction que está disponible solo para transacciones ejecutadas mientras se ejecuta en modo de nodo de archivo completo. Deberá buscar el código de CREATE
operación, la dirección de la cuenta recién creada estará encima del stack
siguiente código de operación para la misma profundidad de llamada (o 0x0 si CREATE
no tuvo éxito). Luego busque su código de bytes en la base de datos leveldb.
Otra opción es usar la callTracer
introducida en geth 1.8, que puede extraer llamadas internas, incluidas CREATE
https://github.com/ethereum/go-ethereum/pull/15516 . Dan un ejemplo en el que puede crear una suscripción a través de ipc y obtener transacciones internas de múltiples bloques:
$ nc -U /work/temp/rinkeby/geth.ipc
{"id": 1, "method": "debug_subscribe", "params": ["traceChain", "0x0",
"0xffff", {"tracer": "callTracer"}]}
{"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"}}}
[P]: recorrer el trie completo bloque a bloque es muy probablemente ineficiente. ¿Hay alguna manera de atravesar solo los caminos que cambiaron desde el último bloque?
Creo que es posible calcular eficientemente la diferencia de 2 Patricia Merkle Tries. La idea general es tomar 2 raíces, verificar sus mordiscos, bajar el trie solo para mordiscos que son diferentes en ambas raíces. Repítalo recursivamente para los nodos de nivel inferior. Habrá algunas complicaciones relacionadas con los nodos de hoja/extensión, pero creo que se pueden solucionar.
Otra opción es realizar un seguimiento de los nodos de Patricia Trie que ya atravesó en bloques anteriores y omitirlos para bloques posteriores.
ivicaa
medvedev1088
ivicaa