As a developer, sooner rather than later you’ll want to start interacting with geth and the Ethereum Classic network via your own programs and not manually through the console. To aid this, geth has built-in support for a JSON-RPC based APIs (standard APIs and geth specific APIs). These can be exposed via HTTP, WebSockets and IPC (UNIX sockets on UNIX based platforms, and named pipes on Windows).
The IPC interface is enabled by default and exposes all the APIs supported by geth, whereas the HTTP and WS interfaces need to manually be enabled and only expose a subset of APIs due to security reasons. These can be turned on/off and configured as you’d expect.
HTTP based JSON-RPC API options:
--http Enable the HTTP-RPC server
--http.addr HTTP-RPC server listening interface (default: localhost)
--http.port HTTP-RPC server listening port (default: 8545)
--http.api API’s offered over the HTTP-RPC interface (default: eth,net,web3)
--http.corsdomain Comma separated list of domains from which to accept cross origin requests (browser enforced)
--ws Enable the WS-RPC server
--ws.addr WS-RPC server listening interface (default: localhost)
--ws.port WS-RPC server listening port (default: 8546)
--ws.api API’s offered over the WS-RPC interface (default: eth,net,web3)
--ws.origins Origins from which to accept websockets requests
--graphql Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.
--graphql.corsdomain Comma separated list of domains from which to accept cross origin requests (browser enforced)
--graphql.vhosts Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts ‘*’ wildcard. (default: “localhost”)
--ipcdisable Disable the IPC-RPC server
--ipcapi API’s offered over the IPC-RPC interface (default: admin,debug,eth,miner,net,personal,shh,txpool,web3)
--ipcpath Filename for IPC socket/pipe within the datadir (explicit paths escape it)
You’ll need to use your own programming environments’ capabilities (libraries, tools, etc) to connect via HTTP, WS or IPC to a geth node configured with the above flags and you’ll need to speak JSON-RPC on all transports. You can reuse the same connection for multiple requests! Here you can check the available JSON-RPC calls.
Attention
Please understand the security implications of opening up an HTTP/WS based transport before doing so! Hackers on the internet are actively trying to subvert Ethereum nodes with exposed APIs! Further, all browser tabs can access locally running web servers, so malicious web pages could try to subvert locally available APIs!
Last update: 2023-08-18
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/admin/index.html b/JSON-RPC-API/modules/admin/index.html
new file mode 100644
index 0000000000..3be0fc6154
--- /dev/null
+++ b/JSON-RPC-API/modules/admin/index.html
@@ -0,0 +1,1355 @@
+ Admin - CoreGeth Documentation
func(api*adminAPI)AddPeer(urlstring)(bool,error){
+server:=api.node.Server()
+ifserver==nil{
+returnfalse,ErrNodeStopped
+}
+node,err:=enode.Parse(enode.ValidSchemes,url)
+iferr!=nil{
+returnfalse,fmt.Errorf("invalid enode: %v",err)
+}
+server.AddPeer(node)
+returntrue,nil
+}// AddPeer requests connecting to a remote node, and also maintaining the new
+// connection at all times, even reconnecting if it is lost.
+
func(api*adminAPI)AddTrustedPeer(urlstring)(bool,error){
+server:=api.node.Server()
+ifserver==nil{
+returnfalse,ErrNodeStopped
+}
+node,err:=enode.Parse(enode.ValidSchemes,url)
+iferr!=nil{
+returnfalse,fmt.Errorf("invalid enode: %v",err)
+}
+server.AddTrustedPeer(node)
+returntrue,nil
+}// AddTrustedPeer allows a remote node to always connect, even if slots are full
+
func(api*AdminAPI)ExportChain(filestring,first*uint64,last*uint64)(bool,error){
+iffirst==nil&&last!=nil{
+returnfalse,errors.New("last cannot be specified without first")
+}
+iffirst!=nil&&last==nil{
+head:=api.eth.BlockChain().CurrentHeader().Number.Uint64()
+last=&head
+}
+if_,err:=os.Stat(file);err==nil{
+returnfalse,errors.New("location would overwrite an existing file")
+}
+out,err:=os.OpenFile(file,os.O_CREATE|os.O_WRONLY|os.O_TRUNC,os.ModePerm)
+iferr!=nil{
+returnfalse,err
+}
+deferout.Close()
+varwriterio.Writer=out
+ifstrings.HasSuffix(file,".gz"){
+writer=gzip.NewWriter(writer)
+deferwriter.(*gzip.Writer).Close()
+}
+iffirst!=nil{
+iferr:=api.eth.BlockChain().ExportN(writer,*first,*last);err!=nil{
+returnfalse,err
+}
+}elseiferr:=api.eth.BlockChain().Export(writer);err!=nil{
+returnfalse,err
+}
+returntrue,nil
+}// ExportChain exports the current blockchain into a local file,
+// or a range of blocks if first and last are non-nil.
+
func(api*AdminAPI)MaxPeers(nint)(bool,error){
+api.eth.handler.maxPeers=n
+api.eth.p2pServer.MaxPeers=n
+fori:=api.eth.handler.peers.len();i>n;i=api.eth.handler.peers.len(){
+p:=api.eth.handler.peers.WorstPeer()
+ifp==nil{
+break
+}
+api.eth.handler.removePeer(p.ID())
+}
+returntrue,nil
+}// MaxPeers sets the maximum peer limit for the protocol manager and the p2p server.
+
func(api*adminAPI)NodeInfo()(*p2p.NodeInfo,error){
+server:=api.node.Server()
+ifserver==nil{
+returnnil,ErrNodeStopped
+}
+returnserver.NodeInfo(),nil
+}// NodeInfo retrieves all the information we know about the host node at the
+// protocol granularity.
+
func(api*adminAPI)Peers()([// Peers retrieves all the information we know about each individual peer at the
+// protocol granularity.
+]*p2p.PeerInfo,error){
+server:=api.node.Server()
+ifserver==nil{
+returnnil,ErrNodeStopped
+}
+returnserver.PeersInfo(),nil
+}
+
func(api*adminAPI)RemoveTrustedPeer(urlstring)(bool,error){
+server:=api.node.Server()
+ifserver==nil{
+returnfalse,ErrNodeStopped
+}
+node,err:=enode.Parse(enode.ValidSchemes,url)
+iferr!=nil{
+returnfalse,fmt.Errorf("invalid enode: %v",err)
+}
+server.RemoveTrustedPeer(node)
+returntrue,nil
+}// RemoveTrustedPeer removes a remote node from the trusted peer set, but it
+// does not disconnect it automatically.
+
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/debug/index.html b/JSON-RPC-API/modules/debug/index.html
new file mode 100644
index 0000000000..6fcfa08f32
--- /dev/null
+++ b/JSON-RPC-API/modules/debug/index.html
@@ -0,0 +1,9235 @@
+ Debug - CoreGeth Documentation
func(*HandlerT)BacktraceAt(locationstring)error{
+returnglogger.BacktraceAt(location)
+}// BacktraceAt sets the log backtrace location. See package log for details on
+// the pattern syntax.
+
BlockProfile turns on goroutine profiling for nsec seconds and writes profile data to file. It uses a profile rate of 1 for most accurate information. If a different rate is desired, set the rate and write the profile manually.
func(*HandlerT)BlockProfile(filestring,nsecuint)error{
+runtime.SetBlockProfileRate(1)
+time.Sleep(time.Duration(nsec)*time.Second)
+deferruntime.SetBlockProfileRate(0)
+returnwriteProfile("block",file)
+}// BlockProfile turns on goroutine profiling for nsec seconds and writes profile data to
+// file. It uses a profile rate of 1 for most accurate information. If a different rate is
+// desired, set the rate and write the profile manually.
+
func(api*DebugAPI)ChaindbCompact()error{
+forb:=byte(0);b<255;b++{
+log.Info("Compacting chain database","range",fmt.Sprintf("0x%0.2X-0x%0.2X",b,b+1))
+iferr:=api.b.ChainDb().Compact([// ChaindbCompact flattens the entire key-value database into a single level,
+// removing all unused slots and merging all keys.
+]byte{b},[]byte{b+1});err!=nil{
+log.Error("Database compaction failed","err",err)
+returnerr
+}
+}
+returnnil
+}
+
func(h*HandlerT)CpuProfile(filestring,nsecuint)error{
+iferr:=h.StartCPUProfile(file);err!=nil{
+returnerr
+}
+time.Sleep(time.Duration(nsec)*time.Second)
+h.StopCPUProfile()
+returnnil
+}// CpuProfile turns on CPU profiling for nsec seconds and writes
+// profile data to file.
+
func(api*DebugAPI)DbAncient(kindstring,numberuint64)(hexutil.Bytes,error){
+returnapi.b.ChainDb().Ancient(kind,number)
+}// DbAncient retrieves an ancient binary blob from the append-only immutable files.
+// It is a mapping to the `AncientReaderOp.Ancient` method
+
func(api*DebugAPI)DbAncients()(uint64,error){
+returnapi.b.ChainDb().Ancients()
+}// DbAncients returns the ancient item numbers in the ancient store.
+// It is a mapping to the `AncientReaderOp.Ancients` method
+
func(api*DebugAPI)DbGet(keystring)(hexutil.Bytes,error){
+blob,err:=common.ParseHexOrString(key)
+iferr!=nil{
+returnnil,err
+}
+returnapi.b.ChainDb().Get(blob)
+}// DbGet returns the raw value of a key stored in the database.
+
func(api*DebugAPI)DumpBlock(blockNrrpc.BlockNumber)(state.Dump,error){
+opts:=&state.DumpConfig{OnlyWithAddresses:true,Max:AccountRangeMaxResults}
+ifblockNr==rpc.PendingBlockNumber{
+_,stateDb:=api.eth.miner.Pending()
+returnstateDb.RawDump(opts),nil
+}
+varblock*types.Block
+ifblockNr==rpc.LatestBlockNumber{
+block=api.eth.blockchain.CurrentBlock()
+}elseifblockNr==rpc.FinalizedBlockNumber{
+block=api.eth.blockchain.CurrentFinalizedBlock()
+}else{
+block=api.eth.blockchain.GetBlockByNumber(uint64(blockNr))
+}
+ifblock==nil{
+returnstate.Dump{},fmt.Errorf("block #%d not found",blockNr)
+}
+stateDb,err:=api.eth.BlockChain().StateAt(block.Root())
+iferr!=nil{
+returnstate.Dump{},err
+}
+returnstateDb.RawDump(opts),nil
+}// DumpBlock retrieves the entire state of the database at a given block.
+
GetAccessibleState returns the first number where the node has accessible state on disk. Note this being the post-state of that block and the pre-state of the next block. The (from, to) parameters are the sequence of blocks to search, which can go either forwards or backwards
func(api*DebugAPI)GetAccessibleState(from,torpc.BlockNumber)(uint64,error){
+db:=api.eth.ChainDb()
+varpivotuint64
+ifp:=rawdb.ReadLastPivotNumber(db);p!=nil{
+pivot=*p
+log.Info("Found fast-sync pivot marker","number",pivot)
+}
+varresolveNum=func(numrpc.BlockNumber)(uint64,error){
+ifnum.Int64()<0{
+block:=api.eth.blockchain.CurrentBlock()
+ifblock==nil{
+return0,fmt.Errorf("current block missing")
+}
+returnblock.NumberU64(),nil
+}
+returnuint64(num.Int64()),nil
+}
+var(
+startuint64
+enduint64
+delta=int64(1)
+lastLogtime.Time
+errerror
+)
+ifstart,err=resolveNum(from);err!=nil{
+return0,err
+}
+ifend,err=resolveNum(to);err!=nil{
+return0,err
+}
+ifstart==end{
+return0,fmt.Errorf("from and to needs to be different")
+}
+ifstart>end{
+delta=-1
+}
+fori:=int64(start);i!=int64(end);i+=delta{
+iftime.Since(lastLog)>8*time.Second{
+log.Info("Finding roots","from",start,"to",end,"at",i)
+lastLog=time.Now()
+}
+ifi<int64(pivot){
+continue
+}
+h:=api.eth.BlockChain().GetHeaderByNumber(uint64(i))
+ifh==nil{
+return0,fmt.Errorf("missing header %d",i)
+}
+ifok,_:=api.eth.ChainDb().Has(h.Root[// GetAccessibleState returns the first number where the node has accessible
+// state on disk. Note this being the post-state of that block and the pre-state
+// of the next block.
+// The (from, to) parameters are the sequence of blocks to search, which can go
+// either forwards or backwards
+:]);ok{
+returnuint64(i),nil
+}
+}
+return0,fmt.Errorf("No state found")
+}
+
func(api*DebugAPI)GetBadBlocks(ctxcontext.Context)([// GetBadBlocks returns a list of the last 'bad blocks' that the client has seen on the network
+// and returns them as a JSON list of block hashes.
+]*BadBlockArgs,error){
+var(
+errerror
+blocks=rawdb.ReadAllBadBlocks(api.eth.chainDb)
+results=make([]*BadBlockArgs,0,len(blocks))
+)
+for_,block:=rangeblocks{
+var(
+blockRlpstring
+blockJSON*ethapi.RPCMarshalBlockT
+)
+ifrlpBytes,err:=rlp.EncodeToBytes(block);err!=nil{
+blockRlp=err.Error()
+}else{
+blockRlp=fmt.Sprintf("0x%x",rlpBytes)
+}
+ifblockJSON,err=ethapi.RPCMarshalBlock(block,true,true,api.eth.APIBackend.ChainConfig());err!=nil{
+blockJSON=ðapi.RPCMarshalBlockT{Error:err.Error()}
+}
+results=append(results,&BadBlockArgs{Hash:block.Hash(),RLP:blockRlp,Block:blockJSON})
+}
+returnresults,nil
+}
+
func(api*DebugAPI)GetBlockRlp(ctxcontext.Context,numberuint64)(hexutil.Bytes,error){
+block,_:=api.b.BlockByNumber(ctx,rpc.BlockNumber(number))
+ifblock==nil{
+returnnil,fmt.Errorf("block #%d not found",number)
+}
+returnrlp.EncodeToBytes(block)
+}// GetBlockRlp retrieves the RLP encoded for of a single block.
+
func(api*DebugAPI)GetHeaderRlp(ctxcontext.Context,numberuint64)(hexutil.Bytes,error){
+header,_:=api.b.HeaderByNumber(ctx,rpc.BlockNumber(number))
+ifheader==nil{
+returnnil,fmt.Errorf("header #%d not found",number)
+}
+returnrlp.EncodeToBytes(header)
+}// GetHeaderRlp retrieves the RLP encoded for of a single header.
+
GetModifiedAccountsByHash returns all accounts that have changed between the two blocks specified. A change is defined as a difference in nonce, balance, code hash, or storage hash.
With one parameter, returns the list of accounts modified in the specified block.
func(api*DebugAPI)GetModifiedAccountsByHash(startHashcommon.Hash,endHash*common.Hash)([// GetModifiedAccountsByHash returns all accounts that have changed between the
+// two blocks specified. A change is defined as a difference in nonce, balance,
+// code hash, or storage hash.
+//
+// With one parameter, returns the list of accounts modified in the specified block.
+]common.Address,error){
+varstartBlock,endBlock*types.Block
+startBlock=api.eth.blockchain.GetBlockByHash(startHash)
+ifstartBlock==nil{
+returnnil,fmt.Errorf("start block %x not found",startHash)
+}
+ifendHash==nil{
+endBlock=startBlock
+startBlock=api.eth.blockchain.GetBlockByHash(startBlock.ParentHash())
+ifstartBlock==nil{
+returnnil,fmt.Errorf("block %x has no parent",endBlock.Number())
+}
+}else{
+endBlock=api.eth.blockchain.GetBlockByHash(*endHash)
+ifendBlock==nil{
+returnnil,fmt.Errorf("end block %x not found",*endHash)
+}
+}
+returnapi.getModifiedAccounts(startBlock,endBlock)
+}
+
GetModifiedAccountsByNumber returns all accounts that have changed between the two blocks specified. A change is defined as a difference in nonce, balance, code hash, or storage hash.
With one parameter, returns the list of accounts modified in the specified block.
func(api*DebugAPI)GetModifiedAccountsByNumber(startNumuint64,endNum*uint64)([// GetModifiedAccountsByNumber returns all accounts that have changed between the
+// two blocks specified. A change is defined as a difference in nonce, balance,
+// code hash, or storage hash.
+//
+// With one parameter, returns the list of accounts modified in the specified block.
+]common.Address,error){
+varstartBlock,endBlock*types.Block
+startBlock=api.eth.blockchain.GetBlockByNumber(startNum)
+ifstartBlock==nil{
+returnnil,fmt.Errorf("start block %x not found",startNum)
+}
+ifendNum==nil{
+endBlock=startBlock
+startBlock=api.eth.blockchain.GetBlockByHash(startBlock.ParentHash())
+ifstartBlock==nil{
+returnnil,fmt.Errorf("block %x has no parent",endBlock.Number())
+}
+}else{
+endBlock=api.eth.blockchain.GetBlockByNumber(*endNum)
+ifendBlock==nil{
+returnnil,fmt.Errorf("end block %d not found",*endNum)
+}
+}
+returnapi.getModifiedAccounts(startBlock,endBlock)
+}
+
func(h*HandlerT)GoTrace(filestring,nsecuint)error{
+iferr:=h.StartGoTrace(file);err!=nil{
+returnerr
+}
+time.Sleep(time.Duration(nsec)*time.Second)
+h.StopGoTrace()
+returnnil
+}// GoTrace turns on tracing for nsec seconds and writes
+// trace data to file.
+
MutexProfile turns on mutex profiling for nsec seconds and writes profile data to file. It uses a profile rate of 1 for most accurate information. If a different rate is desired, set the rate and write the profile manually.
func(*HandlerT)MutexProfile(filestring,nsecuint)error{
+runtime.SetMutexProfileFraction(1)
+time.Sleep(time.Duration(nsec)*time.Second)
+deferruntime.SetMutexProfileFraction(0)
+returnwriteProfile("mutex",file)
+}// MutexProfile turns on mutex profiling for nsec seconds and writes profile data to file.
+// It uses a profile rate of 1 for most accurate information. If a different rate is
+// desired, set the rate and write the profile manually.
+
func(api*DebugAPI)Preimage(ctxcontext.Context,hashcommon.Hash)(hexutil.Bytes,error){
+ifpreimage:=rawdb.ReadPreimage(api.eth.ChainDb(),hash);preimage!=nil{
+returnpreimage,nil
+}
+returnnil,errors.New("unknown preimage")
+}// Preimage is a debug API function that returns the preimage for a sha3 hash, if known.
+
func(api*DebugAPI)RemovePendingTransaction(hashcommon.Hash)(*types.Transaction,error){
+returnapi.eth.txPool.RemoveTx(hash),nil
+}// RemovePendingTransaction removes a transaction from the txpool.
+// It returns the transaction removed, if any.
+
func(*HandlerT)SetGCPercent(vint)int{
+returndebug.SetGCPercent(v)
+}// SetGCPercent sets the garbage collection target percentage. It returns the previous
+// setting. A negative value disables GC.
+
Stacks returns a printed representation of the stacks of all goroutines. It also permits the following optional filters to be used: - filter: boolean expression of packages to filter for
func(*HandlerT)Stacks(filter*string)string{
+buf:=new(bytes.Buffer)
+pprof.Lookup("goroutine").WriteTo(buf,2)
+iffilter!=nil&&len(*filter)>0{
+expanded:=*filter
+expanded=regexp.MustCompile(`[:/\.A-Za-z0-9_-]+`).ReplaceAllString(expanded,"`$0` in Value")
+expanded=regexp.MustCompile("!(`[:/\\.A-Za-z0-9_-]+`)").ReplaceAllString(expanded,"$1 not")
+expanded=strings.ReplaceAll(expanded,"||","or")
+expanded=strings.ReplaceAll(expanded,"&&","and")
+log.Info("Expanded filter expression","filter",*filter,"expanded",expanded)
+expr,err:=bexpr.CreateEvaluator(expanded)
+iferr!=nil{
+log.Error("Failed to parse filter expression","expanded",expanded,"err",err)
+return""
+}
+dump:=buf.String()
+buf.Reset()
+for_,trace:=// Stacks returns a printed representation of the stacks of all goroutines. It
+// also permits the following optional filters to be used:
+// - filter: boolean expression of packages to filter for
+rangestrings.Split(dump,"\n\n"){
+ifok,_:=expr.Evaluate(map[string]string{"Value":trace});ok{
+buf.WriteString(trace)
+buf.WriteString("\n\n")
+}
+}
+}
+returnbuf.String()
+}
+
StandardTraceBadBlockToFile dumps the structured logs created during the execution of EVM against a block pulled from the pool of bad ones to the local file system and returns a list of files to the caller.
func(api*API)StandardTraceBadBlockToFile(ctxcontext.Context,hashcommon.Hash,config*StdTraceConfig)([// StandardTraceBadBlockToFile dumps the structured logs created during the
+// execution of EVM against a block pulled from the pool of bad ones to the
+// local file system and returns a list of files to the caller.
+]string,error){
+block:=rawdb.ReadBadBlock(api.backend.ChainDb(),hash)
+ifblock==nil{
+returnnil,fmt.Errorf("bad block %#x not found",hash)
+}
+returnapi.standardTraceBlockToFile(ctx,block,config)
+}
+
StandardTraceBlockToFile dumps the structured logs created during the execution of EVM to the local file system and returns a list of files to the caller.
func(api*API)StandardTraceBlockToFile(ctxcontext.Context,hashcommon.Hash,config*StdTraceConfig)([// StandardTraceBlockToFile dumps the structured logs created during the
+// execution of EVM to the local file system and returns a list of files
+// to the caller.
+]string,error){
+block,err:=api.blockByHash(ctx,hash)
+iferr!=nil{
+returnnil,err
+}
+returnapi.standardTraceBlockToFile(ctx,block,config)
+}
+
Subscribe creates a subscription to an event channel. Subscriptions are not available over HTTP; they are only available over WS, IPC, and Process connections.
func(sub*RPCDebugSubscription)Subscribe(subscriptionNameRPCDebugSubscriptionParamsName,subscriptionOptionsinterface{})(subscriptionIDrpc.ID,errerror){
+return
+}// Subscribe creates a subscription to an event channel.
+// Subscriptions are not available over HTTP; they are only available over WS, IPC, and Process connections.
+
TraceBadBlock returns the structured logs created during the execution of EVM against a block pulled from the pool of bad ones and returns them as a JSON object.
func(api*API)TraceBadBlock(ctxcontext.Context,hashcommon.Hash,config*TraceConfig)([// TraceBadBlock returns the structured logs created during the execution of
+// EVM against a block pulled from the pool of bad ones and returns them as a JSON
+// object.
+]*txTraceResult,error){
+block:=rawdb.ReadBadBlock(api.backend.ChainDb(),hash)
+ifblock==nil{
+returnnil,fmt.Errorf("bad block %#x not found",hash)
+}
+returnapi.traceBlock(ctx,block,config)
+}
+
func(api*API)TraceBlock(ctxcontext.Context,blobhexutil.Bytes,config*TraceConfig)([// TraceBlock returns the structured logs created during the execution of EVM
+// and returns them as a JSON object.
+]*txTraceResult,error){
+block:=new(types.Block)
+iferr:=rlp.Decode(bytes.NewReader(blob),block);err!=nil{
+returnnil,fmt.Errorf("could not decode block: %v",err)
+}
+returnapi.traceBlock(ctx,block,config)
+}
+
func(api*API)TraceBlockByHash(ctxcontext.Context,hashcommon.Hash,config*TraceConfig)([// TraceBlockByHash returns the structured logs created during the execution of
+// EVM and returns them as a JSON object.
+]*txTraceResult,error){
+block,err:=api.blockByHash(ctx,hash)
+iferr!=nil{
+returnnil,err
+}
+returnapi.traceBlock(ctx,block,config)
+}
+
func(api*API)TraceBlockByNumber(ctxcontext.Context,numberrpc.BlockNumber,config*TraceConfig)([// TraceBlockByNumber returns the structured logs created during the execution of
+// EVM and returns them as a JSON object.
+]*txTraceResult,error){
+block,err:=api.blockByNumber(ctx,number)
+iferr!=nil{
+returnnil,err
+}
+returnapi.traceBlock(ctx,block,config)
+}
+
func(api*API)TraceBlockFromFile(ctxcontext.Context,filestring,config*TraceConfig)([// TraceBlockFromFile returns the structured logs created during the execution of
+// EVM and returns them as a JSON object.
+]*txTraceResult,error){
+blob,err:=os.ReadFile(file)
+iferr!=nil{
+returnnil,fmt.Errorf("could not read file: %v",err)
+}
+returnapi.TraceBlock(ctx,blob,config)
+}
+
TraceCall lets you trace a given eth_call. It collects the structured logs created during the execution of EVM if the given transaction was added on top of the provided block and returns them as a JSON object.
func(api*API)TraceCall(ctxcontext.Context,argsethapi.TransactionArgs,blockNrOrHashrpc.BlockNumberOrHash,config*TraceCallConfig)(interface{},error){
+var(
+errerror
+block*types.Block
+)
+ifhash,ok:=blockNrOrHash.Hash();ok{
+block,err=api.blockByHash(ctx,hash)
+}elseifnumber,ok:=blockNrOrHash.Number();ok{
+ifnumber==rpc.PendingBlockNumber{
+returnnil,errors.New("tracing on top of pending is not supported")
+}
+block,err=api.blockByNumber(ctx,number)
+}else{
+returnnil,errors.New("invalid arguments; neither block nor hash specified")
+}
+iferr!=nil{
+returnnil,err
+}
+reexec:=defaultTraceReexec
+ifconfig!=nil&&config.Reexec!=nil{
+reexec=*config.Reexec
+}
+statedb,err:=api.backend.StateAtBlock(ctx,block,reexec,nil,true,false)
+iferr!=nil{
+returnnil,err
+}
+vmctx:=core.NewEVMBlockContext(block.Header(),api.chainContext(ctx),nil)
+ifconfig!=nil{
+iferr:=config.StateOverrides.Apply(statedb);err!=nil{
+returnnil,err
+}
+config.BlockOverrides.Apply(&vmctx)
+}
+msg,err:=args.ToMessage(api.backend.RPCGasCap(),block.BaseFee())
+iferr!=nil{
+returnnil,err
+}
+traceConfig:=getTraceConfigFromTraceCallConfig(config)
+returnapi.traceTx(ctx,msg,new(Context),vmctx,statedb,traceConfig)
+}// TraceCall lets you trace a given eth_call. It collects the structured logs
+// created during the execution of EVM if the given transaction was added on
+// top of the provided block and returns them as a JSON object.
+// Try to retrieve the specified block
+
TraceCallMany lets you trace a given eth_call. It collects the structured logs created during the execution of EVM if the given transaction was added on top of the provided block and returns them as a JSON object. You can provide -2 as a block number to trace on top of the pending block.
func(api*API)TraceCallMany(ctxcontext.Context,txs[// TraceCallMany lets you trace a given eth_call. It collects the structured logs created during the execution of EVM
+// if the given transaction was added on top of the provided block and returns them as a JSON object.
+// You can provide -2 as a block number to trace on top of the pending block.
+]ethapi.TransactionArgs,blockNrOrHashrpc.BlockNumberOrHash,config*TraceCallConfig)(interface{},error){
+var(
+errerror
+block*types.Block
+)
+ifhash,ok:=blockNrOrHash.Hash();ok{
+block,err=api.blockByHash(ctx,hash)
+}elseifnumber,ok:=blockNrOrHash.Number();ok{
+block,err=api.blockByNumber(ctx,number)
+}else{
+returnnil,errors.New("invalid arguments; neither block nor hash specified")
+}
+iferr!=nil{
+returnnil,err
+}
+reexec:=defaultTraceReexec
+ifconfig!=nil&&config.Reexec!=nil{
+reexec=*config.Reexec
+}
+statedb,err:=api.backend.StateAtBlock(ctx,block,reexec,nil,true,false)
+iferr!=nil{
+returnnil,err
+}
+ifconfig!=nil{
+iferr:=config.StateOverrides.Apply(statedb);err!=nil{
+returnnil,err
+}
+}
+traceConfig:=getTraceConfigFromTraceCallConfig(config)
+varresults=make([// Try to retrieve the specified block
+]interface{},len(txs))
+foridx,args:=rangetxs{
+msg,err:=args.ToMessage(api.backend.RPCGasCap(),block.BaseFee())
+iferr!=nil{
+results[idx]=&txTraceResult{Error:err.Error()}
+continue
+}
+vmctx:=core.NewEVMBlockContext(block.Header(),api.chainContext(ctx),nil)
+res,err:=api.traceTx(ctx,msg,new(Context),vmctx,statedb,traceConfig)
+iferr!=nil{
+results[idx]=&txTraceResult{Error:err.Error()}
+continue
+}
+res,err=decorateResponse(res,traceConfig)
+iferr!=nil{
+returnnil,fmt.Errorf("failed to decorate response for transaction at index %d with error %v",idx,err)
+}
+results[idx]=res
+}
+returnresults,nil
+}
+
func(api*API)TraceChain(ctxcontext.Context,start,endrpc.BlockNumber,config*TraceConfig)(*rpc.Subscription,error){
+from,err:=api.blockByNumber(ctx,start)
+iferr!=nil{
+returnnil,err
+}
+to,err:=api.blockByNumber(ctx,end)
+iferr!=nil{
+returnnil,err
+}
+iffrom.Number().Cmp(to.Number())>=0{
+returnnil,fmt.Errorf("end block (#%d) needs to come after start block (#%d)",end,start)
+}
+returnapi.traceChain(ctx,from,to,config)
+}// TraceChain returns the structured logs created during the execution of EVM
+// between two blocks (excluding start) and returns them as a JSON object.
+
func(api*API)TraceTransaction(ctxcontext.Context,hashcommon.Hash,config*TraceConfig)(interface{},error){
+_,blockHash,blockNumber,index,err:=api.backend.GetTransaction(ctx,hash)
+iferr!=nil{
+returnnil,err
+}
+ifblockNumber==0{
+returnnil,errors.New("genesis is not traceable")
+}
+reexec:=defaultTraceReexec
+ifconfig!=nil&&config.Reexec!=nil{
+reexec=*config.Reexec
+}
+block,err:=api.blockByNumberAndHash(ctx,rpc.BlockNumber(blockNumber),blockHash)
+iferr!=nil{
+returnnil,err
+}
+msg,vmctx,statedb,err:=api.backend.StateAtTransaction(ctx,block,int(index),reexec)
+iferr!=nil{
+returnnil,err
+}
+txctx:=&Context{BlockHash:blockHash,TxIndex:int(index),TxHash:hash}
+returnapi.traceTx(ctx,msg,txctx,vmctx,statedb,config)
+}// TraceTransaction returns the structured logs created during the execution of EVM
+// and returns them as a JSON object.
+
func(*HandlerT)Verbosity(levelint){
+glogger.Verbosity(log.Lvl(level))
+}// Verbosity sets the log verbosity ceiling. The verbosity of individual packages
+// and source files can be raised using Vmodule.
+
func(*HandlerT)Vmodule(patternstring)error{
+returnglogger.Vmodule(pattern)
+}// Vmodule sets the log verbosity pattern. See package log for details on the
+// pattern syntax.
+
func(*HandlerT)WriteBlockProfile(filestring)error{
+returnwriteProfile("block",file)
+}// WriteBlockProfile writes a goroutine blocking profile to the given file.
+
WriteMemProfile writes an allocation profile to the given file. Note that the profiling rate cannot be set through the API, it must be set on the command line.
func(*HandlerT)WriteMemProfile(filestring)error{
+returnwriteProfile("heap",file)
+}// WriteMemProfile writes an allocation profile to the given file.
+// Note that the profiling rate cannot be set through the API,
+// it must be set on the command line.
+
func(*HandlerT)WriteMutexProfile(filestring)error{
+returnwriteProfile("mutex",file)
+}// WriteMutexProfile writes a goroutine blocking profile to the given file.
+
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/eth/index.html b/JSON-RPC-API/modules/eth/index.html
new file mode 100644
index 0000000000..4d40790a7d
--- /dev/null
+++ b/JSON-RPC-API/modules/eth/index.html
@@ -0,0 +1,13425 @@
+ Eth - CoreGeth Documentation
func(s*BlockChainAPI)BlockNumber()hexutil.Uint64{
+header,_:=s.b.HeaderByNumber(context.Background(),rpc.LatestBlockNumber)
+returnhexutil.Uint64(header.Number.Uint64())
+}// BlockNumber returns the block number of the chain head.
+
func(s*BlockChainAPI)Call(ctxcontext.Context,argsTransactionArgs,blockNrOrHashrpc.BlockNumberOrHash,overrides*StateOverride)(hexutil.Bytes,error){
+result,err:=DoCall(ctx,s.b,args,blockNrOrHash,overrides,s.b.RPCEVMTimeout(),s.b.RPCGasCap())
+iferr!=nil{
+returnnil,err
+}
+iflen(result.Revert())>0{
+returnnil,newRevertError(result)
+}
+returnresult.Return(),result.Err
+}// Call executes the given transaction on the state for the given block number.
+//
+// Additionally, the caller can specify a batch of contract for fields overriding.
+//
+// Note, this function doesn't make and changes in the state/blockchain and is
+// useful to execute and retrieve values.
+
ChainId is the EIP-155 replay-protection chain id for the current Ethereum chain config.
Note, this method does not conform to EIP-695 because the configured chain ID is always returned, regardless of the current head block. We used to return an error when the chain wasn’t synced up to a block where EIP-155 is enabled, but this behavior caused issues in CL clients.
func(api*BlockChainAPI)ChainId()*hexutil.Big{
+return(*hexutil.Big)(api.b.ChainConfig().GetChainID())
+}// ChainId is the EIP-155 replay-protection chain id for the current Ethereum chain config.
+//
+// Note, this method does not conform to EIP-695 because the configured chain ID is always
+// returned, regardless of the current head block. We used to return an error when the chain
+// wasn't synced up to a block where EIP-155 is enabled, but this behavior caused issues
+// in CL clients.
+
func(api*EthereumAPI)Coinbase()(common.Address,error){
+returnapi.Etherbase()
+}// Coinbase is the address that mining rewards will be send to (alias for Etherbase).
+
CreateAccessList creates a EIP-2930 type AccessList for the given transaction. Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state.
func(s*BlockChainAPI)CreateAccessList(ctxcontext.Context,argsTransactionArgs,blockNrOrHash*rpc.BlockNumberOrHash)(*accessListResult,error){
+bNrOrHash:=rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
+ifblockNrOrHash!=nil{
+bNrOrHash=*blockNrOrHash
+}
+acl,gasUsed,vmerr,err:=AccessList(ctx,s.b,bNrOrHash,args)
+iferr!=nil{
+returnnil,err
+}
+result:=&accessListResult{Accesslist:&acl,GasUsed:hexutil.Uint64(gasUsed)}
+ifvmerr!=nil{
+result.Error=vmerr.Error()
+}
+returnresult,nil
+}// CreateAccessList creates a EIP-2930 type AccessList for the given transaction.
+// Reexec and BlockNrOrHash can be specified to create the accessList on top of a certain state.
+
func(s*BlockChainAPI)EstimateGas(ctxcontext.Context,argsTransactionArgs,blockNrOrHash*rpc.BlockNumberOrHash)(hexutil.Uint64,error){
+bNrOrHash:=rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber)
+ifblockNrOrHash!=nil{
+bNrOrHash=*blockNrOrHash
+}
+returnDoEstimateGas(ctx,s.b,args,bNrOrHash,s.b.RPCGasCap())
+}// EstimateGas returns an estimate of the amount of gas needed to execute the
+// given transaction against the current pending block.
+
FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields) on a given unsigned transaction, and returns it to the caller for further processing (signing + broadcast).
func(s*TransactionAPI)FillTransaction(ctxcontext.Context,argsTransactionArgs)(*SignTransactionResult,error){
+iferr:=args.setDefaults(ctx,s.b);err!=nil{
+returnnil,err
+}
+tx:=args.toTransaction()
+data,err:=tx.MarshalBinary()
+iferr!=nil{
+returnnil,err
+}
+return&SignTransactionResult{data,tx},nil
+}// FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields)
+// on a given unsigned transaction, and returns it to the caller for further
+// processing (signing + broadcast).
+
func(s*EthereumAPI)GasPrice(ctxcontext.Context)(*hexutil.Big,error){
+tipcap,err:=s.b.SuggestGasTipCap(ctx)
+iferr!=nil{
+returnnil,err
+}
+ifhead:=s.b.CurrentHeader();head.BaseFee!=nil{
+tipcap.Add(tipcap,head.BaseFee)
+}
+return(*hexutil.Big)(tipcap),err
+}// GasPrice returns a suggestion for a gas price for legacy transactions.
+
GetBalance returns the amount of wei for the given address in the state of the given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block numbers are also allowed.
func(s*BlockChainAPI)GetBalance(ctxcontext.Context,addresscommon.Address,blockNrOrHashrpc.BlockNumberOrHash)(*hexutil.Big,error){
+state,_,err:=s.b.StateAndHeaderByNumberOrHash(ctx,blockNrOrHash)
+ifstate==nil||err!=nil{
+returnnil,err
+}
+return(*hexutil.Big)(state.GetBalance(address)),state.Error()
+}// GetBalance returns the amount of wei for the given address in the state of the
+// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta
+// block numbers are also allowed.
+
GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
func(s*BlockChainAPI)GetBlockByHash(ctxcontext.Context,hashcommon.Hash,fullTxbool)(*RPCMarshalBlockT,error){
+block,err:=s.b.BlockByHash(ctx,hash)
+ifblock!=nil{
+returns.rpcMarshalBlock(ctx,block,true,fullTx)
+}
+returnnil,err
+}// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full
+// detail, otherwise only the transaction hash is returned.
+
GetBlockByNumber returns the requested canonical block. * When blockNr is -1 the chain head is returned. * When blockNr is -2 the pending chain head is returned. * When fullTx is true all transactions in the block are returned, otherwise only the transaction hash is returned.
func(s*BlockChainAPI)GetBlockByNumber(ctxcontext.Context,numberrpc.BlockNumber,fullTxbool)(*RPCMarshalBlockT,error){
+block,err:=s.b.BlockByNumber(ctx,number)
+ifblock!=nil&&err==nil{
+response,err:=s.rpcMarshalBlock(ctx,block,true,fullTx)
+iferr==nil&&number==rpc.PendingBlockNumber{
+response.setAsPending()
+}
+returnresponse,err
+}
+returnnil,err
+}// GetBlockByNumber returns the requested canonical block.
+// * When blockNr is -1 the chain head is returned.
+// * When blockNr is -2 the pending chain head is returned.
+// * When fullTx is true all transactions in the block are returned, otherwise
+// only the transaction hash is returned.
+
func(s*TransactionAPI)GetBlockTransactionCountByHash(ctxcontext.Context,blockHashcommon.Hash)*hexutil.Uint{
+ifblock,_:=s.b.BlockByHash(ctx,blockHash);block!=nil{
+n:=hexutil.Uint(len(block.Transactions()))
+return&n
+}
+returnnil
+}// GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash.
+
func(s*TransactionAPI)GetBlockTransactionCountByNumber(ctxcontext.Context,blockNrrpc.BlockNumber)*hexutil.Uint{
+ifblock,_:=s.b.BlockByNumber(ctx,blockNr);block!=nil{
+n:=hexutil.Uint(len(block.Transactions()))
+return&n
+}
+returnnil
+}// GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number.
+
func(s*BlockChainAPI)GetCode(ctxcontext.Context,addresscommon.Address,blockNrOrHashrpc.BlockNumberOrHash)(hexutil.Bytes,error){
+state,_,err:=s.b.StateAndHeaderByNumberOrHash(ctx,blockNrOrHash)
+ifstate==nil||err!=nil{
+returnnil,err
+}
+code:=state.GetCode(address)
+returncode,state.Error()
+}// GetCode returns the code stored at the given address in the state for the given block number.
+
func(api*FilterAPI)GetFilterChanges(idrpc.ID)(interface{},error){
+api.filtersMu.Lock()
+deferapi.filtersMu.Unlock()
+iff,found:=api.filters[id];found{
+if!f.deadline.Stop(){
+<-f.deadline.C
+}
+f.deadline.Reset(api.timeout)
+switchf.typ{
+casePendingTransactionsSubscription,BlocksSubscription,SideBlocksSubscription:
+hashes:=f.hashes
+f.hashes=nil
+returnreturnHashes(hashes),nil
+caseLogsSubscription,MinedAndPendingLogsSubscription:
+logs:=f.logs
+f.logs=nil
+returnreturnLogs(logs),nil
+}
+}
+return[// GetFilterChanges returns the logs for the filter with the given id since
+// last time it was called. This can be used for polling.
+//
+// For pending transaction and block filters the result is []common.Hash.
+// (pending)Log filters return []Log.
+]interface{}{},fmt.Errorf("filter not found")
+}
+
func(api*FilterAPI)GetFilterLogs(ctxcontext.Context,idrpc.ID)([// GetFilterLogs returns the logs for the filter with the given id.
+// If the filter could not be found an empty array of logs is returned.
+]*types.Log,error){
+api.filtersMu.Lock()
+f,found:=api.filters[id]
+api.filtersMu.Unlock()
+if!found||f.typ!=LogsSubscription{
+returnnil,fmt.Errorf("filter not found")
+}
+varfilter*Filter
+iff.crit.BlockHash!=nil{
+filter=NewBlockFilter(api.backend,*f.crit.BlockHash,f.crit.Addresses,f.crit.Topics)
+}else{
+begin:=rpc.LatestBlockNumber.Int64()
+iff.crit.FromBlock!=nil{
+begin=f.crit.FromBlock.Int64()
+}
+end:=rpc.LatestBlockNumber.Int64()
+iff.crit.ToBlock!=nil{
+end=f.crit.ToBlock.Int64()
+}
+filter=NewRangeFilter(api.backend,begin,end,f.crit.Addresses,f.crit.Topics)
+}
+logs,err:=filter.Logs(ctx)
+iferr!=nil{
+returnnil,err
+}
+returnreturnLogs(logs),nil
+}
+
func(api*API)GetHashrate()uint64{
+returnuint64(api.ethash.Hashrate())
+}// GetHashrate returns the current hashrate for local CPU miner and remote miner.
+
GetHeaderByNumber returns the requested canonical block header. * When blockNr is -1 the chain head is returned. * When blockNr is -2 the pending chain head is returned.
func(s*BlockChainAPI)GetHeaderByNumber(ctxcontext.Context,numberrpc.BlockNumber)(*RPCMarshalHeaderT,error){
+header,err:=s.b.HeaderByNumber(ctx,number)
+ifheader!=nil&&err==nil{
+response:=s.rpcMarshalHeader(ctx,header)
+ifnumber==rpc.PendingBlockNumber{
+response.setAsPending()
+}
+returnresponse,err
+}
+returnnil,err
+}// GetHeaderByNumber returns the requested canonical block header.
+// * When blockNr is -1 the chain head is returned.
+// * When blockNr is -2 the pending chain head is returned.
+
func(s*TransactionAPI)GetRawTransactionByBlockHashAndIndex(ctxcontext.Context,blockHashcommon.Hash,indexhexutil.Uint)hexutil.Bytes{
+ifblock,_:=s.b.BlockByHash(ctx,blockHash);block!=nil{
+returnnewRPCRawTransactionFromBlockIndex(block,uint64(index))
+}
+returnnil
+}// GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index.
+
func(s*TransactionAPI)GetRawTransactionByBlockNumberAndIndex(ctxcontext.Context,blockNrrpc.BlockNumber,indexhexutil.Uint)hexutil.Bytes{
+ifblock,_:=s.b.BlockByNumber(ctx,blockNr);block!=nil{
+returnnewRPCRawTransactionFromBlockIndex(block,uint64(index))
+}
+returnnil
+}// GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index.
+
func(s*TransactionAPI)GetRawTransactionByHash(ctxcontext.Context,hashcommon.Hash)(hexutil.Bytes,error){
+tx,_,_,_,err:=s.b.GetTransaction(ctx,hash)
+iferr!=nil{
+returnnil,err
+}
+iftx==nil{
+iftx=s.b.GetPoolTransaction(hash);tx==nil{
+returnnil,nil
+}
+}
+returntx.MarshalBinary()
+}// GetRawTransactionByHash returns the bytes of the transaction for the given hash.
+
GetStorageAt returns the storage from the state at the given address, key and block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block numbers are also allowed.
func(s*BlockChainAPI)GetStorageAt(ctxcontext.Context,addresscommon.Address,keystring,blockNrOrHashrpc.BlockNumberOrHash)(hexutil.Bytes,error){
+state,_,err:=s.b.StateAndHeaderByNumberOrHash(ctx,blockNrOrHash)
+ifstate==nil||err!=nil{
+returnnil,err
+}
+res:=state.GetState(address,common.HexToHash(key))
+returnres[// GetStorageAt returns the storage from the state at the given address, key and
+// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block
+// numbers are also allowed.
+:],state.Error()
+}
+
func(s*TransactionAPI)GetTransactionByBlockHashAndIndex(ctxcontext.Context,blockHashcommon.Hash,indexhexutil.Uint)*RPCTransaction{
+ifblock,_:=s.b.BlockByHash(ctx,blockHash);block!=nil{
+returnnewRPCTransactionFromBlockIndex(block,uint64(index),s.b.ChainConfig())
+}
+returnnil
+}// GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
+
func(s*TransactionAPI)GetTransactionByBlockNumberAndIndex(ctxcontext.Context,blockNrrpc.BlockNumber,indexhexutil.Uint)*RPCTransaction{
+ifblock,_:=s.b.BlockByNumber(ctx,blockNr);block!=nil{
+returnnewRPCTransactionFromBlockIndex(block,uint64(index),s.b.ChainConfig())
+}
+returnnil
+}// GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index.
+
func(s*TransactionAPI)GetTransactionCount(ctxcontext.Context,addresscommon.Address,blockNrOrHashrpc.BlockNumberOrHash)(*hexutil.Uint64,error){
+ifblockNr,ok:=blockNrOrHash.Number();ok&&blockNr==rpc.PendingBlockNumber{
+nonce,err:=s.b.GetPoolNonce(ctx,address)
+iferr!=nil{
+returnnil,err
+}
+return(*hexutil.Uint64)(&nonce),nil
+}
+state,_,err:=s.b.StateAndHeaderByNumberOrHash(ctx,blockNrOrHash)
+ifstate==nil||err!=nil{
+returnnil,err
+}
+nonce:=state.GetNonce(address)
+return(*hexutil.Uint64)(&nonce),state.Error()
+}// GetTransactionCount returns the number of transactions the given address has sent for the given block number
+
GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true all transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
func(s*BlockChainAPI)GetUncleByBlockHashAndIndex(ctxcontext.Context,blockHashcommon.Hash,indexhexutil.Uint)(*RPCMarshalBlockT,error){
+block,err:=s.b.BlockByHash(ctx,blockHash)
+ifblock!=nil{
+uncles:=block.Uncles()
+ifindex>=hexutil.Uint(len(uncles)){
+log.Debug("Requested uncle not found","number",block.Number(),"hash",blockHash,"index",index)
+returnnil,nil
+}
+block=types.NewBlockWithHeader(uncles[index])
+returns.rpcMarshalBlock(ctx,block,false,false)
+}
+returnnil,err
+}// GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true
+// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
+
GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true all transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
func(s*BlockChainAPI)GetUncleByBlockNumberAndIndex(ctxcontext.Context,blockNrrpc.BlockNumber,indexhexutil.Uint)(*RPCMarshalBlockT,error){
+block,err:=s.b.BlockByNumber(ctx,blockNr)
+ifblock!=nil{
+uncles:=block.Uncles()
+ifindex>=hexutil.Uint(len(uncles)){
+log.Debug("Requested uncle not found","number",blockNr,"hash",block.Hash(),"index",index)
+returnnil,nil
+}
+block=types.NewBlockWithHeader(uncles[index])
+returns.rpcMarshalBlock(ctx,block,false,false)
+}
+returnnil,err
+}// GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true
+// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
+
func(s*BlockChainAPI)GetUncleCountByBlockHash(ctxcontext.Context,blockHashcommon.Hash)*hexutil.Uint{
+ifblock,_:=s.b.BlockByHash(ctx,blockHash);block!=nil{
+n:=hexutil.Uint(len(block.Uncles()))
+return&n
+}
+returnnil
+}// GetUncleCountByBlockHash returns number of uncles in the block for the given block hash
+
func(s*BlockChainAPI)GetUncleCountByBlockNumber(ctxcontext.Context,blockNrrpc.BlockNumber)*hexutil.Uint{
+ifblock,_:=s.b.BlockByNumber(ctx,blockNr);block!=nil{
+n:=hexutil.Uint(len(block.Uncles()))
+return&n
+}
+returnnil
+}// GetUncleCountByBlockNumber returns number of uncles in the block for the given block number
+
func(s*EthereumAPI)MaxPriorityFeePerGas(ctxcontext.Context)(*hexutil.Big,error){
+tipcap,err:=s.b.SuggestGasTipCap(ctx)
+iferr!=nil{
+returnnil,err
+}
+return(*hexutil.Big)(tipcap),err
+}// MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions.
+
NewBlockFilter creates a filter that fetches blocks that are imported into the chain. It is part of the filter package since polling goes with eth_getFilterChanges.
func(api*FilterAPI)NewBlockFilter()rpc.ID{
+var(
+headers=make(chan*types.Header)
+headerSub=api.events.SubscribeNewHeads(headers)
+)
+api.filtersMu.Lock()
+api.filters[headerSub.ID]=&filter{typ:BlocksSubscription,deadline:time.NewTimer(api.timeout),hashes:make([// NewBlockFilter creates a filter that fetches blocks that are imported into the chain.
+// It is part of the filter package since polling goes with eth_getFilterChanges.
+]common.Hash,0),s:headerSub}
+api.filtersMu.Unlock()
+gofunc(){
+for{
+select{
+caseh:=<-headers:
+api.filtersMu.Lock()
+iff,found:=api.filters[headerSub.ID];found{
+f.hashes=append(f.hashes,h.Hash())
+}
+api.filtersMu.Unlock()
+case<-headerSub.Err():
+api.filtersMu.Lock()
+delete(api.filters,headerSub.ID)
+api.filtersMu.Unlock()
+return
+}
+}
+}()
+returnheaderSub.ID
+}
+
NewFilter creates a new filter and returns the filter id. It can be used to retrieve logs when the state changes. This method cannot be used to fetch logs that are already stored in the state.
Default criteria for the from and to block are “latest”. Using “latest” as block number will return logs for mined blocks. Using “pending” as block number returns logs for not yet mined (pending) blocks. In case logs are removed (chain reorg) previously returned logs are returned again but with the removed property set to true.
In case “fromBlock” > “toBlock” an error is returned.
func(api*FilterAPI)NewFilter(critFilterCriteria)(rpc.ID,error){
+logs:=make(chan[// NewFilter creates a new filter and returns the filter id. It can be
+// used to retrieve logs when the state changes. This method cannot be
+// used to fetch logs that are already stored in the state.
+//
+// Default criteria for the from and to block are "latest".
+// Using "latest" as block number will return logs for mined blocks.
+// Using "pending" as block number returns logs for not yet mined (pending) blocks.
+// In case logs are removed (chain reorg) previously returned logs are returned
+// again but with the removed property set to true.
+//
+// In case "fromBlock" > "toBlock" an error is returned.
+]*types.Log)
+logsSub,err:=api.events.SubscribeLogs(ethereum.FilterQuery(crit),logs)
+iferr!=nil{
+return"",err
+}
+api.filtersMu.Lock()
+api.filters[logsSub.ID]=&filter{typ:LogsSubscription,crit:crit,deadline:time.NewTimer(api.timeout),logs:make([]*types.Log,0),s:logsSub}
+api.filtersMu.Unlock()
+gofunc(){
+for{
+select{
+casel:=<-logs:
+api.filtersMu.Lock()
+iff,found:=api.filters[logsSub.ID];found{
+f.logs=append(f.logs,l...)
+}
+api.filtersMu.Unlock()
+case<-logsSub.Err():
+api.filtersMu.Lock()
+delete(api.filters,logsSub.ID)
+api.filtersMu.Unlock()
+return
+}
+}
+}()
+returnlogsSub.ID,nil
+}
+
func(api*FilterAPI)NewHeads(ctxcontext.Context)(*rpc.Subscription,error){
+notifier,supported:=rpc.NotifierFromContext(ctx)
+if!supported{
+return&rpc.Subscription{},rpc.ErrNotificationsUnsupported
+}
+rpcSub:=notifier.CreateSubscription()
+gofunc(){
+headers:=make(chan*types.Header)
+headersSub:=api.events.SubscribeNewHeads(headers)
+for{
+select{
+caseh:=<-headers:
+notifier.Notify(rpcSub.ID,h)
+case<-rpcSub.Err():
+headersSub.Unsubscribe()
+return
+case<-notifier.Closed():
+headersSub.Unsubscribe()
+return
+}
+}
+}()
+returnrpcSub,nil
+}// NewHeads send a notification each time a new (header) block is appended to the chain.
+
func(api*FilterAPI)NewPendingTransactionFilter()rpc.ID{
+var(
+pendingTxs=make(chan[// NewPendingTransactionFilter creates a filter that fetches pending transaction hashes
+// as transactions enter the pending state.
+//
+// It is part of the filter package because this filter can be used through the
+// `eth_getFilterChanges` polling method that is also used for log filters.
+]common.Hash)
+pendingTxSub=api.events.SubscribePendingTxs(pendingTxs)
+)
+api.filtersMu.Lock()
+api.filters[pendingTxSub.ID]=&filter{typ:PendingTransactionsSubscription,deadline:time.NewTimer(api.timeout),hashes:make([]common.Hash,0),s:pendingTxSub}
+api.filtersMu.Unlock()
+gofunc(){
+for{
+select{
+caseph:=<-pendingTxs:
+api.filtersMu.Lock()
+iff,found:=api.filters[pendingTxSub.ID];found{
+f.hashes=append(f.hashes,ph...)
+}
+api.filtersMu.Unlock()
+case<-pendingTxSub.Err():
+api.filtersMu.Lock()
+delete(api.filters,pendingTxSub.ID)
+api.filtersMu.Unlock()
+return
+}
+}
+}()
+returnpendingTxSub.ID
+}
+
NewPendingTransactions creates a subscription that is triggered each time a transaction enters the transaction pool and was signed from one of the transactions this nodes manages.
func(api*FilterAPI)NewPendingTransactions(ctxcontext.Context)(*rpc.Subscription,error){
+notifier,supported:=rpc.NotifierFromContext(ctx)
+if!supported{
+return&rpc.Subscription{},rpc.ErrNotificationsUnsupported
+}
+rpcSub:=notifier.CreateSubscription()
+gofunc(){
+txHashes:=make(chan[// NewPendingTransactions creates a subscription that is triggered each time a transaction
+// enters the transaction pool and was signed from one of the transactions this nodes manages.
+]common.Hash,128)
+pendingTxSub:=api.events.SubscribePendingTxs(txHashes)
+for{
+select{
+casehashes:=<-txHashes:
+for_,h:=rangehashes{
+notifier.Notify(rpcSub.ID,h)
+}
+case<-rpcSub.Err():
+pendingTxSub.Unsubscribe()
+return
+case<-notifier.Closed():
+pendingTxSub.Unsubscribe()
+return
+}
+}
+}()
+returnrpcSub,nil
+}
+
NewSideBlockFilter creates a filter that fetches blocks that are imported into the chain with a non-canonical status. It is part of the filter package since polling goes with eth_getFilterChanges.
func(api*FilterAPI)NewSideBlockFilter()rpc.ID{
+var(
+headers=make(chan*types.Header)
+headerSub=api.events.SubscribeNewSideHeads(headers)
+)
+api.filtersMu.Lock()
+api.filters[headerSub.ID]=&filter{typ:SideBlocksSubscription,deadline:time.NewTimer(api.timeout),hashes:make([// NewSideBlockFilter creates a filter that fetches blocks that are imported into the chain with a non-canonical status.
+// It is part of the filter package since polling goes with eth_getFilterChanges.
+]common.Hash,0),s:headerSub}
+api.filtersMu.Unlock()
+gofunc(){
+for{
+select{
+caseh:=<-headers:
+api.filtersMu.Lock()
+iff,found:=api.filters[headerSub.ID];found{
+f.hashes=append(f.hashes,h.Hash())
+}
+api.filtersMu.Unlock()
+case<-headerSub.Err():
+api.filtersMu.Lock()
+delete(api.filters,headerSub.ID)
+api.filtersMu.Unlock()
+return
+}
+}
+}()
+returnheaderSub.ID
+}
+
func(api*FilterAPI)NewSideHeads(ctxcontext.Context)(*rpc.Subscription,error){
+notifier,supported:=rpc.NotifierFromContext(ctx)
+if!supported{
+return&rpc.Subscription{},rpc.ErrNotificationsUnsupported
+}
+rpcSub:=notifier.CreateSubscription()
+gofunc(){
+headers:=make(chan*types.Header)
+headersSub:=api.events.SubscribeNewSideHeads(headers)
+for{
+select{
+caseh:=<-headers:
+notifier.Notify(rpcSub.ID,h)
+case<-rpcSub.Err():
+headersSub.Unsubscribe()
+return
+case<-notifier.Closed():
+headersSub.Unsubscribe()
+return
+}
+}
+}()
+returnrpcSub,nil
+}// NewSideHeads send a notification each time a new non-canonical (header) block is written to the database.
+
func(s*TransactionAPI)PendingTransactions()([// PendingTransactions returns the transactions that are in the transaction pool
+// and have a from address that is one of the accounts this node manages.
+]*RPCTransaction,error){
+pending,err:=s.b.GetPoolTransactions()
+iferr!=nil{
+returnnil,err
+}
+accounts:=make(map[common.Address]struct{})
+for_,wallet:=ranges.b.AccountManager().Wallets(){
+for_,account:=rangewallet.Accounts(){
+accounts[account.Address]=struct{}{}
+}
+}
+curHeader:=s.b.CurrentHeader()
+transactions:=make([]*RPCTransaction,0,len(pending))
+for_,tx:=rangepending{
+from,_:=types.Sender(s.signer,tx)
+if_,exists:=accounts[from];exists{
+transactions=append(transactions,newRPCPendingTransaction(tx,curHeader,s.b.ChainConfig()))
+}
+}
+returntransactions,nil
+}
+
Resend accepts an existing transaction and a new gas price and limit. It will remove the given transaction from the pool and reinsert it with the new gas price and limit.
func(s*TransactionAPI)Resend(ctxcontext.Context,sendArgsTransactionArgs,gasPrice*hexutil.Big,gasLimit*hexutil.Uint64)(common.Hash,error){
+ifsendArgs.Nonce==nil{
+returncommon.Hash{},fmt.Errorf("missing transaction nonce in transaction spec")
+}
+iferr:=sendArgs.setDefaults(ctx,s.b);err!=nil{
+returncommon.Hash{},err
+}
+matchTx:=sendArgs.toTransaction()
+varprice=matchTx.GasPrice()
+ifgasPrice!=nil{
+price=gasPrice.ToInt()
+}
+vargas=matchTx.Gas()
+ifgasLimit!=nil{
+gas=uint64(*gasLimit)
+}
+iferr:=checkTxFee(price,gas,s.b.RPCTxFeeCap());err!=nil{
+returncommon.Hash{},err
+}
+pending,err:=s.b.GetPoolTransactions()
+iferr!=nil{
+returncommon.Hash{},err
+}
+for_,p:=// Resend accepts an existing transaction and a new gas price and limit. It will remove
+// the given transaction from the pool and reinsert it with the new gas price and limit.
+// Before replacing the old transaction, ensure the _new_ transaction fee is reasonable.
+rangepending{
+wantSigHash:=s.signer.Hash(matchTx)
+pFrom,err:=types.Sender(s.signer,p)
+iferr==nil&&pFrom==sendArgs.from()&&s.signer.Hash(p)==wantSigHash{
+ifgasPrice!=nil&&(*big.Int)(gasPrice).Sign()!=0{
+sendArgs.GasPrice=gasPrice
+}
+ifgasLimit!=nil&&*gasLimit!=0{
+sendArgs.Gas=gasLimit
+}
+signedTx,err:=s.sign(sendArgs.from(),sendArgs.toTransaction())
+iferr!=nil{
+returncommon.Hash{},err
+}
+iferr=s.b.SendTx(ctx,signedTx);err!=nil{
+returncommon.Hash{},err
+}
+returnsignedTx.Hash(),nil
+}
+}
+returncommon.Hash{},fmt.Errorf("transaction %#x not found",matchTx.Hash())
+}
+
SendRawTransaction will add the signed transaction to the transaction pool. The sender is responsible for signing the transaction and using the correct nonce.
func(s*TransactionAPI)SendRawTransaction(ctxcontext.Context,inputhexutil.Bytes)(common.Hash,error){
+tx:=new(types.Transaction)
+iferr:=tx.UnmarshalBinary(input);err!=nil{
+returncommon.Hash{},err
+}
+returnSubmitTransaction(ctx,s.b,tx)
+}// SendRawTransaction will add the signed transaction to the transaction pool.
+// The sender is responsible for signing the transaction and using the correct nonce.
+
func(s*TransactionAPI)SendTransaction(ctxcontext.Context,argsTransactionArgs)(common.Hash,error){
+account:=accounts.Account{Address:args.from()}
+wallet,err:=s.b.AccountManager().Find(account)
+iferr!=nil{
+returncommon.Hash{},err
+}
+ifargs.Nonce==nil{
+s.nonceLock.LockAddr(args.from())
+defers.nonceLock.UnlockAddr(args.from())
+}
+iferr:=args.setDefaults(ctx,s.b);err!=nil{
+returncommon.Hash{},err
+}
+tx:=args.toTransaction()
+signed,err:=wallet.SignTx(account,tx,s.b.ChainConfig().GetChainID())
+iferr!=nil{
+returncommon.Hash{},err
+}
+returnSubmitTransaction(ctx,s.b,signed)
+}// SendTransaction creates a transaction for the given argument, sign it and submit it to the
+// transaction pool.
+
func(s*TransactionAPI)Sign(addrcommon.Address,datahexutil.Bytes)(hexutil.Bytes,error){
+account:=accounts.Account{Address:addr}
+wallet,err:=s.b.AccountManager().Find(account)
+iferr!=nil{
+returnnil,err
+}
+signature,err:=wallet.SignText(account,data)
+iferr==nil{
+signature[64]+=27
+}
+returnsignature,err
+}// Sign calculates an ECDSA signature for:
+// keccak256("\x19Ethereum Signed Message:\n" + len(message) + message).
+//
+// Note, the produced signature conforms to the secp256k1 curve R, S and V values,
+// where the V value will be 27 or 28 for legacy reasons.
+//
+// The account associated with addr must be unlocked.
+//
+// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign
+
SignTransaction will sign the given transaction with the from account. The node needs to have the private key of the account corresponding with the given from address and it needs to be unlocked.
func(s*TransactionAPI)SignTransaction(ctxcontext.Context,argsTransactionArgs)(*SignTransactionResult,error){
+ifargs.Gas==nil{
+returnnil,fmt.Errorf("gas not specified")
+}
+ifargs.GasPrice==nil&&(args.MaxPriorityFeePerGas==nil||args.MaxFeePerGas==nil){
+returnnil,fmt.Errorf("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas")
+}
+ifargs.Nonce==nil{
+returnnil,fmt.Errorf("nonce not specified")
+}
+iferr:=args.setDefaults(ctx,s.b);err!=nil{
+returnnil,err
+}
+tx:=args.toTransaction()
+iferr:=checkTxFee(tx.GasPrice(),tx.Gas(),s.b.RPCTxFeeCap());err!=nil{
+returnnil,err
+}
+signed,err:=s.sign(args.from(),tx)
+iferr!=nil{
+returnnil,err
+}
+data,err:=signed.MarshalBinary()
+iferr!=nil{
+returnnil,err
+}
+return&SignTransactionResult{data,signed},nil
+}// SignTransaction will sign the given transaction with the from account.
+// The node needs to have the private key of the account corresponding with
+// the given from address and it needs to be unlocked.
+
SubmitHashrate can be used for remote miners to submit their hash rate. This enables the node to report the combined hash rate of all miners which submit work through this node.
It accepts the miner hash rate and an identifier which must be unique between nodes.
func(api*API)SubmitHashrate(ratehexutil.Uint64,idcommon.Hash)bool{
+ifapi.ethash.remote==nil{
+returnfalse
+}
+vardone=make(chanstruct{},1)
+select{
+caseapi.ethash.remote.submitRateCh<-&hashrate{done:done,rate:uint64(rate),id:id}:
+case<-api.ethash.remote.exitCh:
+returnfalse
+}
+<-done
+returntrue
+}// SubmitHashrate can be used for remote miners to submit their hash rate.
+// This enables the node to report the combined hash rate of all miners
+// which submit work through this node.
+//
+// It accepts the miner hash rate and an identifier which must be unique
+// between nodes.
+
SubmitWork can be used by external miner to submit their POW solution. It returns an indication if the work was accepted. Note either an invalid solution, a stale work a non-existent work will return false.
func(api*API)SubmitWork(noncetypes.BlockNonce,hash,digestcommon.Hash)bool{
+ifapi.ethash.remote==nil{
+returnfalse
+}
+varerrc=make(chanerror,1)
+select{
+caseapi.ethash.remote.submitWorkCh<-&mineResult{nonce:nonce,mixDigest:digest,hash:hash,errc:errc}:
+case<-api.ethash.remote.exitCh:
+returnfalse
+}
+err:=<-errc
+returnerr==nil
+}// SubmitWork can be used by external miner to submit their POW solution.
+// It returns an indication if the work was accepted.
+// Note either an invalid solution, a stale work a non-existent work will return false.
+
Subscribe creates a subscription to an event channel. Subscriptions are not available over HTTP; they are only available over WS, IPC, and Process connections.
- oneOf:
+
+ - description: `Fires a notification each time a new header is appended to the chain, including chain reorganizations.`
+ - enum: newHeads
+ - type: string
+
+
+ - description: `Fires a notification each time a new header is appended to the non-canonical (side) chain, including chain reorganizations.`
+ - enum: newSideHeads
+ - type: string
+
+
+ - description: `Returns logs that are included in new imported blocks and match the given filter criteria.`
+ - enum: logs
+ - type: string
+
+
+ - description: `Returns the hash for all transactions that are added to the pending state and are signed with a key that is available in the node.`
+ - enum: newPendingTransactions
+ - type: string
+
+
+ - description: `Indicates when the node starts or stops synchronizing. The result can either be a boolean indicating that the synchronization has started (true), finished (false) or an object with various progress indicators.`
+ - enum: syncing
+ - type: string
+
+
+- title: `subscriptionName`
+
{
+ "oneOf": [
+ {
+ "description": "Fires a notification each time a new header is appended to the chain, including chain reorganizations.",
+ "enum": [
+ "newHeads"
+ ],
+ "type": [
+ "string"
+ ]
+ },
+ {
+ "description": "Fires a notification each time a new header is appended to the non-canonical (side) chain, including chain reorganizations.",
+ "enum": [
+ "newSideHeads"
+ ],
+ "type": [
+ "string"
+ ]
+ },
+ {
+ "description": "Returns logs that are included in new imported blocks and match the given filter criteria.",
+ "enum": [
+ "logs"
+ ],
+ "type": [
+ "string"
+ ]
+ },
+ {
+ "description": "Returns the hash for all transactions that are added to the pending state and are signed with a key that is available in the node.",
+ "enum": [
+ "newPendingTransactions"
+ ],
+ "type": [
+ "string"
+ ]
+ },
+ {
+ "description": "Indicates when the node starts or stops synchronizing. The result can either be a boolean indicating that the synchronization has started (true), finished (false) or an object with various progress indicators.",
+ "enum": [
+ "syncing"
+ ],
+ "type": [
+ "string"
+ ]
+ }
+ ],
+ "title": "subscriptionName"
+}
+
func(sub*RPCEthSubscription)Subscribe(subscriptionNameRPCEthSubscriptionParamsName,subscriptionOptionsinterface{})(subscriptionIDrpc.ID,errerror){
+return
+}// Subscribe creates a subscription to an event channel.
+// Subscriptions are not available over HTTP; they are only available over WS, IPC, and Process connections.
+
Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not yet received the latest block headers from its pears. In case it is synchronizing: - startingBlock: block number this node started to synchronise from - currentBlock: block number this node is currently importing - highestBlock: block number of the highest block header this node has received from peers - pulledStates: number of state entries processed until now - knownStates: number of known state entries that still need to be pulled
func(s*EthereumAPI)Syncing()(interface{},error){
+progress:=s.b.SyncProgress()
+ifprogress.CurrentBlock>=progress.HighestBlock{
+returnfalse,nil
+}
+returnmap// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not
+// yet received the latest block headers from its pears. In case it is synchronizing:
+// - startingBlock: block number this node started to synchronise from
+// - currentBlock: block number this node is currently importing
+// - highestBlock: block number of the highest block header this node has received from peers
+// - pulledStates: number of state entries processed until now
+// - knownStates: number of known state entries that still need to be pulled
+[string]interface{}{"startingBlock":hexutil.Uint64(progress.StartingBlock),"currentBlock":hexutil.Uint64(progress.CurrentBlock),"highestBlock":hexutil.Uint64(progress.HighestBlock),"syncedAccounts":hexutil.Uint64(progress.SyncedAccounts),"syncedAccountBytes":hexutil.Uint64(progress.SyncedAccountBytes),"syncedBytecodes":hexutil.Uint64(progress.SyncedBytecodes),"syncedBytecodeBytes":hexutil.Uint64(progress.SyncedBytecodeBytes),"syncedStorage":hexutil.Uint64(progress.SyncedStorage),"syncedStorageBytes":hexutil.Uint64(progress.SyncedStorageBytes),"healedTrienodes":hexutil.Uint64(progress.HealedTrienodes),"healedTrienodeBytes":hexutil.Uint64(progress.HealedTrienodeBytes),"healedBytecodes":hexutil.Uint64(progress.HealedBytecodes),"healedBytecodeBytes":hexutil.Uint64(progress.HealedBytecodeBytes),"healingTrienodes":hexutil.Uint64(progress.HealingTrienodes),"healingBytecode":hexutil.Uint64(progress.HealingBytecode)},nil
+}
+
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/ethash/index.html b/JSON-RPC-API/modules/ethash/index.html
new file mode 100644
index 0000000000..6744e96074
--- /dev/null
+++ b/JSON-RPC-API/modules/ethash/index.html
@@ -0,0 +1,307 @@
+ Ethash - CoreGeth Documentation
func(api*API)GetHashrate()uint64{
+returnuint64(api.ethash.Hashrate())
+}// GetHashrate returns the current hashrate for local CPU miner and remote miner.
+
SubmitHashrate can be used for remote miners to submit their hash rate. This enables the node to report the combined hash rate of all miners which submit work through this node.
It accepts the miner hash rate and an identifier which must be unique between nodes.
func(api*API)SubmitHashrate(ratehexutil.Uint64,idcommon.Hash)bool{
+ifapi.ethash.remote==nil{
+returnfalse
+}
+vardone=make(chanstruct{},1)
+select{
+caseapi.ethash.remote.submitRateCh<-&hashrate{done:done,rate:uint64(rate),id:id}:
+case<-api.ethash.remote.exitCh:
+returnfalse
+}
+<-done
+returntrue
+}// SubmitHashrate can be used for remote miners to submit their hash rate.
+// This enables the node to report the combined hash rate of all miners
+// which submit work through this node.
+//
+// It accepts the miner hash rate and an identifier which must be unique
+// between nodes.
+
SubmitWork can be used by external miner to submit their POW solution. It returns an indication if the work was accepted. Note either an invalid solution, a stale work a non-existent work will return false.
func(api*API)SubmitWork(noncetypes.BlockNonce,hash,digestcommon.Hash)bool{
+ifapi.ethash.remote==nil{
+returnfalse
+}
+varerrc=make(chanerror,1)
+select{
+caseapi.ethash.remote.submitWorkCh<-&mineResult{nonce:nonce,mixDigest:digest,hash:hash,errc:errc}:
+case<-api.ethash.remote.exitCh:
+returnfalse
+}
+err:=<-errc
+returnerr==nil
+}// SubmitWork can be used by external miner to submit their POW solution.
+// It returns an indication if the work was accepted.
+// Note either an invalid solution, a stale work a non-existent work will return false.
+
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/miner/index.html b/JSON-RPC-API/modules/miner/index.html
new file mode 100644
index 0000000000..43c9bcb2ae
--- /dev/null
+++ b/JSON-RPC-API/modules/miner/index.html
@@ -0,0 +1,203 @@
+ Miner - CoreGeth Documentation
func(api*MinerAPI)SetEtherbase(etherbasecommon.Address)bool{
+api.e.SetEtherbase(etherbase)
+returntrue
+}// SetEtherbase sets the etherbase of the miner.
+
func(api*MinerAPI)SetExtra(extrastring)(bool,error){
+iferr:=api.e.Miner().SetExtra([// SetExtra sets the extra data string that is included when this miner mines a block.
+]byte(extra));err!=nil{
+returnfalse,err
+}
+returntrue,nil
+}
+
func(api*MinerAPI)SetGasLimit(gasLimithexutil.Uint64)bool{
+api.e.Miner().SetGasCeil(uint64(gasLimit))
+returntrue
+}// SetGasLimit sets the gaslimit to target towards during mining.
+
func(api*MinerAPI)SetGasPrice(gasPricehexutil.Big)bool{
+api.e.lock.Lock()
+api.e.gasPrice=(*big.Int)(&gasPrice)
+api.e.lock.Unlock()
+api.e.txPool.SetGasPrice((*big.Int)(&gasPrice))
+returntrue
+}// SetGasPrice sets the minimum accepted gas price for the miner.
+
func(api*MinerAPI)SetRecommitInterval(intervalint){
+api.e.Miner().SetRecommitInterval(time.Duration(interval)*time.Millisecond)
+}// SetRecommitInterval updates the interval for miner sealing work recommitting.
+
Start starts the miner with the given number of threads. If threads is nil, the number of workers started is equal to the number of logical CPUs that are usable by this process. If mining is already running, this method adjust the number of threads allowed to use and updates the minimum price required by the transaction pool.
func(api*MinerAPI)Start(threads*int)error{
+ifthreads==nil{
+returnapi.e.StartMining(runtime.NumCPU())
+}
+returnapi.e.StartMining(*threads)
+}// Start starts the miner with the given number of threads. If threads is nil,
+// the number of workers started is equal to the number of logical CPUs that are
+// usable by this process. If mining is already running, this method adjust the
+// number of threads allowed to use and updates the minimum price required by the
+// transaction pool.
+
func(api*MinerAPI)Stop(){
+api.e.StopMining()
+}// Stop terminates the miner, both at the consensus engine level as well as at
+// the block creation level.
+
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/net/index.html b/JSON-RPC-API/modules/net/index.html
new file mode 100644
index 0000000000..ee1db805b6
--- /dev/null
+++ b/JSON-RPC-API/modules/net/index.html
@@ -0,0 +1,47 @@
+ Net - CoreGeth Documentation
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/personal/index.html b/JSON-RPC-API/modules/personal/index.html
new file mode 100644
index 0000000000..659ca4fd89
--- /dev/null
+++ b/JSON-RPC-API/modules/personal/index.html
@@ -0,0 +1,1799 @@
+ Personal - CoreGeth Documentation
func(s*PersonalAccountAPI)DeriveAccount(urlstring,pathstring,pin*bool)(accounts.Account,error){
+wallet,err:=s.am.Wallet(url)
+iferr!=nil{
+returnaccounts.Account{},err
+}
+derivPath,err:=accounts.ParseDerivationPath(path)
+iferr!=nil{
+returnaccounts.Account{},err
+}
+ifpin==nil{
+pin=new(bool)
+}
+returnwallet.Derive(derivPath,*pin)
+}// DeriveAccount requests a HD wallet to derive a new account, optionally pinning
+// it for later reuse.
+
EcRecover returns the address for the account that was used to create the signature. Note, this function is compatible with eth_sign and personal_sign. As such it recovers the address of: hash = keccak256(“\x19Ethereum Signed Message:\n”${message length}${message}) addr = ecrecover(hash, signature)
Note, the signature must conform to the secp256k1 curve R, S and V values, where the V value must be 27 or 28 for legacy reasons.
func(s*PersonalAccountAPI)EcRecover(ctxcontext.Context,data,sighexutil.Bytes)(common.Address,error){
+iflen(sig)!=crypto.SignatureLength{
+returncommon.Address{},fmt.Errorf("signature must be %d bytes long",crypto.SignatureLength)
+}
+ifsig[crypto.RecoveryIDOffset]!=27&&sig[crypto.RecoveryIDOffset]!=28{
+returncommon.Address{},fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)")
+}
+sig[crypto.RecoveryIDOffset]-=27
+rpk,err:=crypto.SigToPub(accounts.TextHash(data),sig)
+iferr!=nil{
+returncommon.Address{},err
+}
+returncrypto.PubkeyToAddress(*rpk),nil
+}// EcRecover returns the address for the account that was used to create the signature.
+// Note, this function is compatible with eth_sign and personal_sign. As such it recovers
+// the address of:
+// hash = keccak256("\x19Ethereum Signed Message:\n"${message length}${message})
+// addr = ecrecover(hash, signature)
+//
+// Note, the signature must conform to the secp256k1 curve R, S and V values, where
+// the V value must be 27 or 28 for legacy reasons.
+//
+// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover
+
func(s*PersonalAccountAPI)ImportRawKey(privkeystring,passwordstring)(common.Address,error){
+key,err:=crypto.HexToECDSA(privkey)
+iferr!=nil{
+returncommon.Address{},err
+}
+ks,err:=fetchKeystore(s.am)
+iferr!=nil{
+returncommon.Address{},err
+}
+acc,err:=ks.ImportECDSA(key,password)
+returnacc.Address,err
+}// ImportRawKey stores the given hex encoded ECDSA key into the key directory,
+// encrypting it with the passphrase.
+
func(s*PersonalAccountAPI)InitializeWallet(ctxcontext.Context,urlstring)(string,error){
+wallet,err:=s.am.Wallet(url)
+iferr!=nil{
+return"",err
+}
+entropy,err:=bip39.NewEntropy(256)
+iferr!=nil{
+return"",err
+}
+mnemonic,err:=bip39.NewMnemonic(entropy)
+iferr!=nil{
+return"",err
+}
+seed:=bip39.NewSeed(mnemonic,"")
+switchwallet:=wallet.(// InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key.
+type){
+case*scwallet.Wallet:
+returnmnemonic,wallet.Initialize(seed)
+default:
+return"",fmt.Errorf("specified wallet does not support initialization")
+}
+}
+
func(s*PersonalAccountAPI)ListAccounts()[// ListAccounts will return a list of addresses for accounts this node manages.
+]common.Address{
+returns.am.Accounts()
+}
+
func(s*PersonalAccountAPI)ListWallets()[// ListWallets will return a list of wallets this node manages.
+]rawWallet{
+wallets:=make([]rawWallet,0)
+for_,wallet:=ranges.am.Wallets(){
+status,failure:=wallet.Status()
+raw:=rawWallet{URL:wallet.URL().String(),Status:status,Accounts:wallet.Accounts()}
+iffailure!=nil{
+raw.Failure=failure.Error()
+}
+wallets=append(wallets,raw)
+}
+returnwallets
+}
+
func(s*PersonalAccountAPI)LockAccount(addrcommon.Address)bool{
+ifks,err:=fetchKeystore(s.am);err==nil{
+returnks.Lock(addr)==nil
+}
+returnfalse
+}// LockAccount will lock the account associated with the given address when it's unlocked.
+
func(s*PersonalAccountAPI)NewAccount(passwordstring)(common.Address,error){
+ks,err:=fetchKeystore(s.am)
+iferr!=nil{
+returncommon.Address{},err
+}
+acc,err:=ks.NewAccount(password)
+iferr==nil{
+log.Info("Your new key was generated","address",acc.Address)
+log.Warn("Please backup your key file!","path",acc.URL.Path)
+log.Warn("Please remember your password!")
+returnacc.Address,nil
+}
+returncommon.Address{},err
+}// NewAccount will create a new account and returns the address for the new account.
+
OpenWallet initiates a hardware wallet opening procedure, establishing a USB connection and attempting to authenticate via the provided passphrase. Note, the method may return an extra challenge requiring a second open (e.g. the Trezor PIN matrix challenge).
func(s*PersonalAccountAPI)OpenWallet(urlstring,passphrase*string)error{
+wallet,err:=s.am.Wallet(url)
+iferr!=nil{
+returnerr
+}
+pass:=""
+ifpassphrase!=nil{
+pass=*passphrase
+}
+returnwallet.Open(pass)
+}// OpenWallet initiates a hardware wallet opening procedure, establishing a USB
+// connection and attempting to authenticate via the provided passphrase. Note,
+// the method may return an extra challenge requiring a second open (e.g. the
+// Trezor PIN matrix challenge).
+
SendTransaction will create a transaction from the given arguments and tries to sign it with the key associated with args.From. If the given passwd isn’t able to decrypt the key it fails.
func(s*PersonalAccountAPI)SendTransaction(ctxcontext.Context,argsTransactionArgs,passwdstring)(common.Hash,error){
+ifargs.Nonce==nil{
+s.nonceLock.LockAddr(args.from())
+defers.nonceLock.UnlockAddr(args.from())
+}
+signed,err:=s.signTransaction(ctx,&args,passwd)
+iferr!=nil{
+log.Warn("Failed transaction send attempt","from",args.from(),"to",args.To,"value",args.Value.ToInt(),"err",err)
+returncommon.Hash{},err
+}
+returnSubmitTransaction(ctx,s.b,signed)
+}// SendTransaction will create a transaction from the given arguments and
+// tries to sign it with the key associated with args.From. If the given
+// passwd isn't able to decrypt the key it fails.
+
func(s*PersonalAccountAPI)Sign(ctxcontext.Context,datahexutil.Bytes,addrcommon.Address,passwdstring)(hexutil.Bytes,error){
+account:=accounts.Account{Address:addr}
+wallet,err:=s.b.AccountManager().Find(account)
+iferr!=nil{
+returnnil,err
+}
+signature,err:=wallet.SignTextWithPassphrase(account,passwd,data)
+iferr!=nil{
+log.Warn("Failed data sign attempt","address",addr,"err",err)
+returnnil,err
+}
+signature[crypto.RecoveryIDOffset]+=27
+returnsignature,nil
+}// Sign calculates an Ethereum ECDSA signature for:
+// keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))
+//
+// Note, the produced signature conforms to the secp256k1 curve R, S and V values,
+// where the V value will be 27 or 28 for legacy reasons.
+//
+// The key used to calculate the signature is decrypted with the given password.
+//
+// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign
+
SignTransaction will create a transaction from the given arguments and tries to sign it with the key associated with args.From. If the given passwd isn’t able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast to other nodes
func(s*PersonalAccountAPI)SignTransaction(ctxcontext.Context,argsTransactionArgs,passwdstring)(*SignTransactionResult,error){
+ifargs.From==nil{
+returnnil,fmt.Errorf("sender not specified")
+}
+ifargs.Gas==nil{
+returnnil,fmt.Errorf("gas not specified")
+}
+ifargs.GasPrice==nil&&(args.MaxFeePerGas==nil||args.MaxPriorityFeePerGas==nil){
+returnnil,fmt.Errorf("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas")
+}
+ifargs.Nonce==nil{
+returnnil,fmt.Errorf("nonce not specified")
+}
+tx:=args.toTransaction()
+iferr:=checkTxFee(tx.GasPrice(),tx.Gas(),s.b.RPCTxFeeCap());err!=nil{
+returnnil,err
+}
+signed,err:=s.signTransaction(ctx,&args,passwd)
+iferr!=nil{
+log.Warn("Failed transaction sign attempt","from",args.from(),"to",args.To,"value",args.Value.ToInt(),"err",err)
+returnnil,err
+}
+data,err:=signed.MarshalBinary()
+iferr!=nil{
+returnnil,err
+}
+return&SignTransactionResult{data,signed},nil
+}// SignTransaction will create a transaction from the given arguments and
+// tries to sign it with the key associated with args.From. If the given passwd isn't
+// able to decrypt the key it fails. The transaction is returned in RLP-form, not broadcast
+// to other nodes
+
UnlockAccount will unlock the account associated with the given address with the given password for duration seconds. If duration is nil it will use a default of 300 seconds. It returns an indication if the account was unlocked.
func(s*PersonalAccountAPI)UnlockAccount(ctxcontext.Context,addrcommon.Address,passwordstring,duration*uint64)(bool,error){
+ifs.b.ExtRPCEnabled()&&!s.b.AccountManager().Config().InsecureUnlockAllowed{
+returnfalse,errors.New("account unlock with HTTP access is forbidden")
+}
+constmax=uint64(time.Duration(math.MaxInt64)/time.Second)
+vardtime.Duration
+ifduration==nil{
+d=300*time.Second
+}elseif*duration>max{
+returnfalse,errors.New("unlock duration too large")
+}else{
+d=time.Duration(*duration)*time.Second
+}
+ks,err:=fetchKeystore(s.am)
+iferr!=nil{
+returnfalse,err
+}
+err=ks.TimedUnlock(accounts.Account{Address:addr},password,d)
+iferr!=nil{
+log.Warn("Failed account unlock attempt","address",addr,"err",err)
+}
+returnerr==nil,err
+}// UnlockAccount will unlock the account associated with the given address with
+// the given password for duration seconds. If duration is nil it will use a
+// default of 300 seconds. It returns an indication if the account was unlocked.
+
func(s*PersonalAccountAPI)Unpair(ctxcontext.Context,urlstring,pinstring)error{
+wallet,err:=s.am.Wallet(url)
+iferr!=nil{
+returnerr
+}
+switchwallet:=wallet.(// Unpair deletes a pairing between wallet and geth.
+type){
+case*scwallet.Wallet:
+returnwallet.Unpair([]byte(pin))
+default:
+returnfmt.Errorf("specified wallet does not support pairing")
+}
+}
+
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/trace/index.html b/JSON-RPC-API/modules/trace/index.html
new file mode 100644
index 0000000000..2e9d092497
--- /dev/null
+++ b/JSON-RPC-API/modules/trace/index.html
@@ -0,0 +1,2753 @@
+ Trace - CoreGeth Documentation
Block returns the structured logs created during the execution of EVM and returns them as a JSON object. The correct name will be TraceBlockByNumber, though we want to be compatible with Parity trace module.
func(api*TraceAPI)Block(ctxcontext.Context,numberrpc.BlockNumber,config*TraceConfig)([// Block returns the structured logs created during the execution of
+// EVM and returns them as a JSON object.
+// The correct name will be TraceBlockByNumber, though we want to be compatible with Parity trace module.
+]interface{},error){
+config=setTraceConfigDefaultTracer(config)
+block,err:=api.debugAPI.blockByNumber(ctx,number)
+iferr!=nil{
+returnnil,err
+}
+traceResults,err:=api.debugAPI.traceBlock(ctx,block,config)
+iferr!=nil{
+returnnil,err
+}
+traceReward,err:=api.traceBlockReward(ctx,block,config)
+iferr!=nil{
+returnnil,err
+}
+traceUncleRewards,err:=api.traceBlockUncleRewards(ctx,block,config)
+iferr!=nil{
+returnnil,err
+}
+results:=[]interface{}{}
+for_,result:=rangetraceResults{
+ifresult.Error!=""{
+returnnil,errors.New(result.Error)
+}
+vartmpinterface{}
+iferr:=json.Unmarshal(result.Result.(json.RawMessage),&tmp);err!=nil{
+returnnil,err
+}
+if*config.Tracer=="stateDiffTracer"{
+results=append(results,tmp)
+}else{
+results=append(results,tmp.([]interface{})...)
+}
+}
+results=append(results,traceReward)
+for_,uncleReward:=rangetraceUncleRewards{
+results=append(results,uncleReward)
+}
+returnresults,nil
+}
+
Call lets you trace a given eth_call. It collects the structured logs created during the execution of EVM if the given transaction was added on top of the provided block and returns them as a JSON object. You can provide -2 as a block number to trace on top of the pending block.
func(api*TraceAPI)Call(ctxcontext.Context,argsethapi.TransactionArgs,blockNrOrHashrpc.BlockNumberOrHash,config*TraceCallConfig)(interface{},error){
+config=setTraceCallConfigDefaultTracer(config)
+res,err:=api.debugAPI.TraceCall(ctx,args,blockNrOrHash,config)
+iferr!=nil{
+returnnil,err
+}
+traceConfig:=getTraceConfigFromTraceCallConfig(config)
+returndecorateResponse(res,traceConfig)
+}// Call lets you trace a given eth_call. It collects the structured logs created during the execution of EVM
+// if the given transaction was added on top of the provided block and returns them as a JSON object.
+// You can provide -2 as a block number to trace on top of the pending block.
+
CallMany lets you trace a given eth_call. It collects the structured logs created during the execution of EVM if the given transaction was added on top of the provided block and returns them as a JSON object. You can provide -2 as a block number to trace on top of the pending block.
func(api*TraceAPI)CallMany(ctxcontext.Context,txs[// CallMany lets you trace a given eth_call. It collects the structured logs created during the execution of EVM
+// if the given transaction was added on top of the provided block and returns them as a JSON object.
+// You can provide -2 as a block number to trace on top of the pending block.
+]ethapi.TransactionArgs,blockNrOrHashrpc.BlockNumberOrHash,config*TraceCallConfig)(interface{},error){
+config=setTraceCallConfigDefaultTracer(config)
+returnapi.debugAPI.TraceCallMany(ctx,txs,blockNrOrHash,config)
+}
+
Filter configures a new tracer according to the provided configuration, and executes all the transactions contained within. The return value will be one item per transaction, dependent on the requested tracer.
func(api*TraceAPI)Filter(ctxcontext.Context,argsTraceFilterArgs,config*TraceConfig)(*rpc.Subscription,error){
+config=setTraceConfigDefaultTracer(config)
+start:=rpc.BlockNumber(args.FromBlock)
+end:=rpc.BlockNumber(args.ToBlock)
+returnapi.debugAPI.TraceChain(ctx,start,end,config)
+}// Filter configures a new tracer according to the provided configuration, and
+// executes all the transactions contained within. The return value will be one item
+// per transaction, dependent on the requested tracer.
+
Subscribe creates a subscription to an event channel. Subscriptions are not available over HTTP; they are only available over WS, IPC, and Process connections.
func(sub*RPCTraceSubscription)Subscribe(subscriptionNameRPCTraceSubscriptionParamsName,subscriptionOptionsinterface{})(subscriptionIDrpc.ID,errerror){
+return
+}// Subscribe creates a subscription to an event channel.
+// Subscriptions are not available over HTTP; they are only available over WS, IPC, and Process connections.
+
func(api*TraceAPI)Transaction(ctxcontext.Context,hashcommon.Hash,config*TraceConfig)(interface{},error){
+config=setTraceConfigDefaultTracer(config)
+returnapi.debugAPI.TraceTransaction(ctx,hash,config)
+}// Transaction returns the structured logs created during the execution of EVM
+// and returns them as a JSON object.
+
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/txpool/index.html b/JSON-RPC-API/modules/txpool/index.html
new file mode 100644
index 0000000000..ffe50d4c76
--- /dev/null
+++ b/JSON-RPC-API/modules/txpool/index.html
@@ -0,0 +1,1333 @@
+ Txpool - CoreGeth Documentation
func(s*TxPoolAPI)Inspect()map// Inspect retrieves the content of the transaction pool and flattens it into an
+// easily inspectable list.
+[string]map[string]map[string]string{
+content:=map[string]map[string]map[string]string{"pending":make(map[string]map[string]string),"queued":make(map[string]map[string]string)}
+pending,queue:=s.b.TxPoolContent()
+varformat=func(tx*types.Transaction)string{
+ifto:=tx.To();to!=nil{
+returnfmt.Sprintf("%s: %v wei + %v gas × %v wei",tx.To().Hex(),tx.Value(),tx.Gas(),tx.GasPrice())
+}
+returnfmt.Sprintf("contract creation: %v wei + %v gas × %v wei",tx.Value(),tx.Gas(),tx.GasPrice())
+}
+foraccount,txs:=// Define a formatter to flatten a transaction into a string
+rangepending{
+dump:=make(map[string]string)
+for_,tx:=rangetxs{
+dump[fmt.Sprintf("%d",tx.Nonce())]=format(tx)
+}
+content["pending"][account.Hex()]=dump
+}
+foraccount,txs:=rangequeue{
+dump:=make(map[string]string)
+for_,tx:=rangetxs{
+dump[fmt.Sprintf("%d",tx.Nonce())]=format(tx)
+}
+content["queued"][account.Hex()]=dump
+}
+returncontent
+}
+
func(s*TxPoolAPI)Status()map// Status returns the number of pending and queued transaction in the pool.
+[string]hexutil.Uint{
+pending,queue:=s.b.Stats()
+returnmap[string]hexutil.Uint{"pending":hexutil.Uint(pending),"queued":hexutil.Uint(queue)}
+}
+
\ No newline at end of file
diff --git a/JSON-RPC-API/modules/web3/index.html b/JSON-RPC-API/modules/web3/index.html
new file mode 100644
index 0000000000..9d6531c108
--- /dev/null
+++ b/JSON-RPC-API/modules/web3/index.html
@@ -0,0 +1,63 @@
+ Web3 - CoreGeth Documentation
func(s*web3API)Sha3(inputhexutil.Bytes)hexutil.Bytes{
+returncrypto.Keccak256(input)
+}// Sha3 applies the ethereum sha3 implementation on the input.
+// It assumes the input is hex encoded.
+
CoreGeth supports OpenRPC’s Service Discovery method, enabling efficient and well-spec’d JSON RPC interfacing and tooling. This method follows the established JSON RPC patterns, and is accessible via HTTP, WebSocket, IPC, and console servers. To use this method:
The trace module is for getting a deeper insight into transaction processing. It includes two sets of calls; the transaction trace filtering API and the ad-hoc tracing API. You can find the documentation for the supported methods here.
It’s good to mention that trace_* methods are nothing more than aliases to some existing debug_* methods. The reason for creating those aliases, was to reach compatibility with OpenEthereum’s (aka Parity) trace module, which has been requested by the community in order they can fully use core-geth. For achieving this, the trace_* methods set the default tracer to callTracerParity if none is set.
Full sync
In order to use the Transaction-Trace Filtering API, core-geth must be fully synced using --syncmode=full --gcmode=archive. Otherwise, you can set the number of blocks to reexec back for rebuilding the state, though taking longer for a trace call to finish.
The ad-hoc tracing API allows you to perform a number of different diagnostics on calls or transactions, either historical ones from the chain or hypothetical ones not yet mined.
callTracerParity Transaction trace returning a response equivalent to OpenEthereum’s (aka Parity) response schema. For documentation on this response value see here.
vmTrace Virtual Machine execution trace. Provides a full trace of the VM’s state throughout the execution of the transaction, including for any subcalls. (Not implemented yet)
stateDiffTracer State difference. Provides information detailing all altered portions of the Ethereum state made due to the execution of the transaction. For documentation on this response value see here.
Example trace_* API method config (last method argument)
1
+2
+3
+4
+5
+6
{
+"tracer":"stateDiffTracer",
+"timeout: "10s",
+ "reexec:"10000",// number of block to reexec back for calculating state
+"nestedTraceOutput":true// in Ad-hoc Tracing methods the response is nested similar to OpenEthereum's output
+}
+
The output result is an array including the outer transaction (first object in the array), as well the internal transactions (next objects in the array) that were being triggered.
Each object that represents an internal transaction consists of:
the action object with all the call args,
the resutls object with the outcome as well the gas used,
the subtraces field, representing the number of internal transactions that were being triggered by the current transaction,
the traceAddress field, representing the exact nesting location in the call trace [index in root, index in first CALL, index in second CALL, …].
Provides information detailing all altered portions of the Ethereum state made due to the execution of the transaction.
Each address object provides the state differences for balance, nonce, code and storage. Actually, under the storage object, we can find the state differences for each contract’s storage key.
Special symbols explanation:
+, when we have a new entry in the state DB,
-, when we have a removal from the state DB,
*, when existing data have changed in the state DB, providing the from (old) and the to (new) values,
SSTORE in some edge cases persists data in state but are not being returned on stateDiff storage results on OpenEthereum output.
Happens only on 2 transactions on Mordor testnet, as of block 2,519,999. (TX hashes: 0xab73afe7b92ad9b537df3f168de0d06f275ed34edf9e19b36362ac6fa304c0bf, 0x15a7c727a9bbfdd43d09805288668cc4a0ec647772d717957e882a71ace80b1a)
When error ErrInsufficientFundsForTransfer happens, OpenEthereum leaves the tracer run producing negative balances, though using safe math for overflows it returns 0 balance, on the other hand the to account receives the full amount. Core-geth removes only the gas cost from the sender and adds it to the coinbase balance.
Same as in 2, but on top of that, the sender account doesn’t have to pay for the gas cost even. In this case, core-geth returns an empty JSON, as in reality this transaction will remain in the tx_pool and never be executed, neither change the state.
On OpenEthereum the block gasLimit is set to be U256::max(), which leads into problems on contracts using it for pseudo-randomness. On core-geth, we believe that the user utilising the trace_ wants to see what will happen in reality, though we leave the block untouched to its true values*.
When an internal call fails with out of gas, and its state is not being persisted, we don’t add it in stateDiff output, as it happens on OpenEthereum.
\n }\n \n \n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search result\n *\n * @param result - Search result\n *\n * @returns Element\n */\nexport function renderSearchResult(\n result: SearchResult\n): HTMLElement {\n const threshold = result[0].score\n const docs = [...result]\n\n /* Find and extract parent article */\n const parent = docs.findIndex(doc => !doc.location.includes(\"#\"))\n const [article] = docs.splice(parent, 1)\n\n /* Determine last index above threshold */\n let index = docs.findIndex(doc => doc.score < threshold)\n if (index === -1)\n index = docs.length\n\n /* Partition sections */\n const best = docs.slice(0, index)\n const more = docs.slice(index)\n\n /* Render children */\n const children = [\n renderSearchDocument(article, Flag.PARENT | +(!parent && index === 0)),\n ...best.map(section => renderSearchDocument(section, Flag.TEASER)),\n ...more.length ? [\n \n \n {more.length > 0 && more.length === 1\n ? translation(\"search.result.more.one\")\n : translation(\"search.result.more.other\", more.length)\n }\n \n {...more.map(section => renderSearchDocument(section, Flag.TEASER))}\n \n ] : []\n ]\n\n /* Render search result */\n return (\n
\n {children}\n
\n )\n}\n", "/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SourceFacts } from \"~/components\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render repository facts\n *\n * @param facts - Repository facts\n *\n * @returns Element\n */\nexport function renderSourceFacts(facts: SourceFacts): HTMLElement {\n return (\n
\n {facts.map(fact => (\n
{fact}
\n ))}\n
\n )\n}\n", "/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a table inside a wrapper to improve scrolling on mobile\n *\n * @param table - Table element\n *\n * @returns Element\n */\nexport function renderTable(table: HTMLElement): HTMLElement {\n return (\n
\n
\n {table}\n
\n
\n )\n}\n", "/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { configuration } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Version\n */\nexport interface Version {\n version: string /* Version identifier */\n title: string /* Version title */\n aliases: string[] /* Version aliases */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version\n *\n * @param version - Version\n *\n * @returns Element\n */\nfunction renderVersion(version: Version): HTMLElement {\n const config = configuration()\n\n /* Ensure trailing slash, see https://bit.ly/3rL5u3f */\n const url = new URL(`${version.version}/`, config.base)\n return (\n
\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version selector\n *\n * @param versions - Versions\n *\n * @returns Element\n */\nexport function renderVersionSelector(versions: Version[]): HTMLElement {\n const config = configuration()\n\n /* Determine active version */\n const [, current] = config.base.match(/([^/]+)\\/?$/)!\n const active =\n versions.find(({ version, aliases }) => (\n version === current || aliases.includes(current)\n )) || versions[0]\n\n /* Render version selector */\n return (\n
\n \n {active.title}\n \n
\n {versions.map(renderVersion)}\n
\n
\n )\n}\n", "/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, Subject } from \"rxjs\"\nimport {\n filter,\n finalize,\n map,\n mapTo,\n mergeWith,\n tap\n} from \"rxjs/operators\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Details\n */\nexport interface Details {}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Print mode observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Print mode observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch details\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details observable\n */\nexport function watchDetails(\n el: HTMLDetailsElement, { target$, print$ }: WatchOptions\n): Observable {\n return target$\n .pipe(\n map(target => target.closest(\"details:not([open])\")!),\n filter(details => el === details),\n mergeWith(print$),\n mapTo(el)\n )\n}\n\n/**\n * Mount details\n *\n * This function ensures that `details` tags are opened on anchor jumps and\n * prior to printing, so the whole content of the page is visible.\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details component observable\n */\nexport function mountDetails(\n el: HTMLDetailsElement, options: MountOptions\n): Observable> {\n const internal$ = new Subject()\n internal$.subscribe(() => {\n el.setAttribute(\"open\", \"\")\n el.scrollIntoView()\n })\n\n /* Create and return component */\n return watchDetails(el, options)\n .pipe(\n tap(internal$),\n finalize(() => internal$.complete()),\n mapTo({ ref: el })\n )\n}\n", "/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, of } from \"rxjs\"\n\nimport { createElement, replaceElement } from \"~/browser\"\nimport { renderTable } from \"~/templates\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Data table\n */\nexport interface DataTable {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Sentinel for replacement\n */\nconst sentinel = createElement(\"table\")\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount data table\n *\n * This function wraps a data table in another scrollable container, so it can\n * be smoothly scrolled on smaller screen sizes and won't break the layout.\n *\n * @param el - Data table element\n *\n * @returns Data table component observable\n */\nexport function mountDataTable(\n el: HTMLElement\n): Observable> {\n replaceElement(el, sentinel)\n replaceElement(sentinel, renderTable(el))\n\n /* Create and return component */\n return of({ ref: el })\n}\n", "/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, merge } from \"rxjs\"\n\nimport { Viewport, getElements } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { CodeBlock, mountCodeBlock } from \"../code\"\nimport { Details, mountDetails } from \"../details\"\nimport { DataTable, mountDataTable } from \"../table\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content\n */\nexport type Content =\n | CodeBlock\n | DataTable\n | Details\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n viewport$: Observable /* Viewport observable */\n print$: Observable /* Print mode observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount content\n *\n * This function mounts all components that are found in the content of the\n * actual article, including code blocks, data tables and details.\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Content component observable\n */\nexport function mountContent(\n el: HTMLElement, { target$, viewport$, print$ }: MountOptions\n): Observable> {\n return merge(\n\n /* Code blocks */\n ...getElements(\"pre > code\", el)\n .map(child => mountCodeBlock(child, { viewport$ })),\n\n /* Data tables */\n ...getElements(\"table:not([class])\", el)\n .map(child => mountDataTable(child)),\n\n /* Details */\n ...getElements(\"details\", el)\n .map(child => mountDetails(child, { target$, print$ }))\n )\n}\n", "/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n merge,\n of\n} from \"rxjs\"\nimport {\n delay,\n finalize,\n map,\n observeOn,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport {\n resetDialogState,\n setDialogMessage,\n setDialogState\n} from \"~/actions\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Dialog\n */\nexport interface Dialog {\n message: string /* Dialog message */\n open: boolean /* Dialog is visible */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n alert$: Subject /* Alert subject */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch dialog\n *\n * @param _el - Dialog element\n * @param options - Options\n *\n * @returns Dialog observable\n */\nexport function watchDialog(\n _el: HTMLElement, { alert$ }: WatchOptions\n): Observable