Mira esta transacción:
https://etherscan.io/tx/0x37c469573ca24f538d91f39e9d0b8d49927a36d70496ef74521cbf5c44a056d4
En la consola de geth, si ingreso:
eth.getTransaction('0x37c4...')
Devuelve la transacción con un to
valor de null
. Estoy bastante seguro de que esto se debe a que esta transacción es una implementación de contrato.
Si miro:
eth.getTransactionReceipt('0x37c4...')
con el mismo ID de transacción, el contract address
campo no está vacío.
Mi pregunta: ¿es to
suficiente null
para distinguir una transacción como aquella que implementó un contrato? Y en segundo lugar, ¿mirar el recibo es la única forma de obtener la dirección del contrato?
¿ Q está to
siendo null
suficiente para distinguir una transacción como aquella que desplegó un contrato?
Sí
¿ Q es mirando el recibo la única manera de obtener la dirección del contrato?
Sí, en el cliente go-ethereum. , aunque probablemente también pueda averiguar la dirección del contrato a partir de los resultados de rastreo de la debug.traceTransaction(...)
llamada a la API.
EDITAR: busqué en los debug.traceTransaction(...)
resultados y no pude encontrar la dirección del contrato creado.
Desde el código fuente de go-ethereum eth/api.go, líneas 481-504 a continuación, puede ver que la condición donde se usa la To
dirección para decidir si la transacción es una transacción de creación de contrato:nil
func (s *PrivateAccountAPI) SignAndSendTransaction(args SendTxArgs, passwd string) (common.Hash, error) {
args = prepareSendTxArgs(args, s.gpo)
s.txMu.Lock()
defer s.txMu.Unlock()
if args.Nonce == nil {
args.Nonce = rpc.NewHexNumber(s.txPool.State().GetNonce(args.From))
}
var tx *types.Transaction
if args.To == nil {
tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
} else {
tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
}
signature, err := s.am.SignWithPassphrase(args.From, passwd, tx.SigHash().Bytes())
if err != nil {
return common.Hash{}, err
}
return submitTransaction(s.txPool, tx, signature)
}
Esto se confirma en 4.3 La Transacción en el Libro Amarillo :
donde el símbolo ∅ representa un conjunto vacío.
La búsqueda en el código fuente de go-ethereum para contractAddress muestra que ese getTransactionReceipt(...)
es el método para devolver la dirección del contrato. De eth/api.go, líneas 1083-1132 :
func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (map[string]interface{}, error) {
receipt := core.GetReceipt(s.chainDb, txHash)
if receipt == nil {
glog.V(logger.Debug).Infof("receipt not found for transaction %s", txHash.Hex())
return nil, nil
}
tx, _, err := getTransaction(s.chainDb, s.txPool, txHash)
if err != nil {
glog.V(logger.Debug).Infof("%v\n", err)
return nil, nil
}
txBlock, blockIndex, index, err := getTransactionBlockData(s.chainDb, txHash)
if err != nil {
glog.V(logger.Debug).Infof("%v\n", err)
return nil, nil
}
from, err := tx.FromFrontier()
if err != nil {
glog.V(logger.Debug).Infof("%v\n", err)
return nil, nil
}
fields := map[string]interface{}{
"root": common.Bytes2Hex(receipt.PostState),
"blockHash": txBlock,
"blockNumber": rpc.NewHexNumber(blockIndex),
"transactionHash": txHash,
"transactionIndex": rpc.NewHexNumber(index),
"from": from,
"to": tx.To(),
"gasUsed": rpc.NewHexNumber(receipt.GasUsed),
"cumulativeGasUsed": rpc.NewHexNumber(receipt.CumulativeGasUsed),
"contractAddress": nil,
"logs": receipt.Logs,
}
if receipt.Logs == nil {
fields["logs"] = []vm.Logs{}
}
// If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
if bytes.Compare(receipt.ContractAddress.Bytes(), bytes.Repeat([]byte{0}, 20)) != 0 {
fields["contractAddress"] = receipt.ContractAddress
}
return fields, nil
}
thomas jay prisa
privacidadisahumanright.eth