From fdb82d87f122bd3336a8926ed0bb7a509a130f29 Mon Sep 17 00:00:00 2001
From: Thomas Jay Rush <jrush@quickblocks.io>
Date: Fri, 11 Sep 2020 15:20:00 -0400
Subject: [PATCH] 1070 eth get code (#1100)

* Fixing issue #1070 Add eth_getCode

* Adding eth_getCode to README
---
 README.md                         |  1 +
 cmd/rpcdaemon/commands/eth_api.go | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/README.md b/README.md
index b052a031ac..83bf73dce2 100644
--- a/README.md
+++ b/README.md
@@ -137,6 +137,7 @@ eth_getBlockByHash
 eth_getBlockTransactionCountByHash
 eth_getBlockTransactionCountByNumber
 eth_getBalance
+eth_getCode
 eth_getLogs
 eth_getStorageAt
 eth_getTransactionReceipt
diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go
index 0c7d97cc16..bf969ac146 100644
--- a/cmd/rpcdaemon/commands/eth_api.go
+++ b/cmd/rpcdaemon/commands/eth_api.go
@@ -39,6 +39,7 @@ type EthAPI interface {
 	GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, txIndex hexutil.Uint64) (*RPCTransaction, error)
 	GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, txIndex hexutil.Uint) (*RPCTransaction, error)
 	GetStorageAt(ctx context.Context, address common.Address, index string, blockNrOrHash rpc.BlockNumberOrHash) (string, error)
+	GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error)
 }
 
 // APIImpl is implementation of the EthAPI interface based on remote Db access
@@ -235,3 +236,28 @@ func (api *APIImpl) GetStorageAt(ctx context.Context, address common.Address, in
 
 	return hexutil.Encode(res), nil
 }
+
+// GetCode returns the code stored at the given address in the state for the given block number.
+func (api *APIImpl) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) {
+	blockNumber, _, err := rpchelper.GetBlockNumber(blockNrOrHash, api.dbReader)
+	if err != nil {
+		return nil, err
+	}
+
+	reader := adapter.NewStateReader(api.db, blockNumber)
+	acc, err := reader.ReadAccountData(address)
+	if err != nil {
+		return nil, err
+	}
+
+	if acc == nil {
+		return nil, fmt.Errorf("account %s not found", address)
+	}
+
+	res, err := reader.ReadAccountCode(address, acc.CodeHash)
+	if err != nil {
+		return nil, err
+	}
+
+	return res, nil
+}
-- 
GitLab