以太坊原始碼分析(17)Internal包簡介

尹成發表於2018-05-13
## Internal包簡介

Internal包主要是封裝了js的命令列介面,並且包含了命令列所呼叫的api資訊。

## ethapi/api包分析
ethapi/api包主要是進入js的命令列介面後,輸入的命令實現部分。<br>
js的命令實現在ethapi/api和node/api中。目前一共有三種api的命令。<br>
(1)第一種是admin相關的命令,這個是通過安全的RPC通道實現的。其結構體為PrivateAdminAPI<br>
```
// PrivateAdminAPI is the collection of administrative API methods exposed only
// over a secure RPC channel.
type PrivateAdminAPI struct {
    node *Node // Node interfaced by this API
}
```
(2)第二種是personal相關的命令,主要是負責賬戶管理相關命令,可以lock和unlock賬戶。其結構體為PrivateAccountAPI<br>
```
// PrivateAccountAPI provides an API to access accounts managed by this node.
// It offers methods to create, (un)lock en list accounts. Some methods accept
// passwords and are therefore considered private by default.
type PrivateAccountAPI struct {
    am *accounts.Manager
    nonceLock *AddrLocker
    b Backend
}
```
(3)第三種是eth相關的命令,主要是可以操作區塊上的相關命令。其結構體為PublicBlockChainAPI<br>
```
// PublicBlockChainAPI provides an API to access the Ethereum blockchain.
// It offers only methods that operate on public data that is freely available to anyone.
type PublicBlockChainAPI struct {
    b Backend
}
```

## otto包
以太坊的命令是通過在js虛擬機器上來實現命令的。而在go語言中,有第三方的otto包,可以直接在go語言中實現js命令。而以太坊程式碼則使用了otto包來實現搭建js命令。<br>
在otto包中,set方法是設定變數的值,get方法是獲取變數的值。
```
// Set the property of the given name to the given value.
func (self Object) Set(name string, value interface{})
// Get the value of the property with the given name.
func (self Object) Get(name string) (Value, error)
```
Compile是根據輸入的路徑對js的程式碼進行編譯,返回變數的值。
```
// Compile will parse the given source and return a Script value or nil and
// an error if there was a problem during compilation.
func (self *Otto) Compile(filename string, src interface{}) (*Script, error)
```
Run方法會執行相關的js程式碼,如果有返回值的話會返回。
```
// Run will run the given source (parsing it first if necessary), returning the resulting value and error (if any)
func (self Otto) Run(src interface{}) (Value, error)
```
## 如何編寫自己的以太坊命令
接上篇ethapi.api-analysis分析,如果我們需要在相關模組新增相關命令,首先我們需要找到相關命令所對應的api結構體。<br>
各個命令對應的結構體,包的位置如下:
```
     admin  PrivateAdminAPI,PublicAdminAPI  node/api
     debug  PrivateDebugAPI eth/api
     eth    PublicBlockChainAPI ethapi/api
     miner  PrivateMinerAPI eth/api
     net    PublicNetAPI    ethapi/api
     personal   PrivateAccountAPI   ethapi/api
     txpool PublicTxPoolAPI ethapi/api
     rpc    所有可呼叫包集合
     web3   所有命令集合
```
假設我們需要在personal包中新增一個命令,那麼我們就在PrivateAccountAPI中新增一個方法:
```
func (s *PrivateAccountAPI) TestMethod() {
fmt.Print("TestMethod")
}
```
接下來到internal/web3ext/web3ext.go中,找到personal命令集合,然後新增一條自己的命令:
```
const Personal_JS = `
web3._extend(
methods: [
        new web3._extend.Method({
            name : 'testMethod',
            call : 'personal_testMethod'
        }), //our method
...
```
最後到internal/jsre/deps/web3.js中,找到personal方法的定義:
```
function Personal(web3) {
this._requestManager = web3._requestManager;

var self = this;

methods().forEach(function(method) {
method.attachToObject(self);
method.setRequestManager(self._requestManager);
});

properties().forEach(function(p) {
p.attachToObject(self);
p.setRequestManager(self._requestManager);
});
}
var methods = function () {
...
```
然後再methods中新增你定義的方法名:
```
var methods = function () {
var testMethod = new Method({
name : 'testMethod',
call : 'personal_testMethod'
});
...
```
並在最後的return中新增你的方法:
```
return [
newAccount,
testMethod, //our method
importRawKey,
unlockAccount,
ecRecover,
sign,
sendTransaction,
lockAccount
];
```
這之後在啟動命令列,我們就可以呼叫我們的方法了。結果如下:
```
> personal.testMethod()
TestMethodnull
```




網址:http://www.qukuailianxueyuan.io/



欲領取造幣技術與全套虛擬機器資料

區塊鏈技術交流QQ群:756146052  備註:CSDN

尹成學院微信:備註:CSDN


相關文章