github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/signer/rules/rules_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2018 Go Ethereum作者
    10  //此文件是Go以太坊的一部分。
    11  //
    12  //Go以太坊是免费软件:您可以重新发布和/或修改它
    13  //根据GNU通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊的分布希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU通用公共许可证了解更多详细信息。
    21  //
    22  //你应该已经收到一份GNU通用公共许可证的副本
    23  //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  //
    25  package rules
    26  
    27  import (
    28  	"fmt"
    29  	"math/big"
    30  	"strings"
    31  	"testing"
    32  
    33  	"github.com/ethereum/go-ethereum/accounts"
    34  	"github.com/ethereum/go-ethereum/common"
    35  	"github.com/ethereum/go-ethereum/common/hexutil"
    36  	"github.com/ethereum/go-ethereum/core/types"
    37  	"github.com/ethereum/go-ethereum/internal/ethapi"
    38  	"github.com/ethereum/go-ethereum/signer/core"
    39  	"github.com/ethereum/go-ethereum/signer/storage"
    40  )
    41  
    42  const JS = `
    43  /*
    44  这是一个JavaScript规则文件的示例实现。
    45  
    46  当签名者通过外部API接收到请求时,将计算相应的方法。
    47  可能发生三件事:
    48  
    49  1。方法返回“批准”。这意味着操作是允许的。
    50  2。方法返回“reject”。这意味着操作被拒绝。
    51  三。其他任何内容;其他返回值[*],方法未实现或在处理过程中发生异常。这意味着
    52  操作将继续通过用户选择的常规UI方法进行手动处理。
    53  
    54  [*]注意:未来版本的规则集可能会使用更复杂的基于JSON的返回值,因此可能不会
    55  只响应批准/拒绝/手动,但也修改响应。例如,选择只列出一个,而不是全部
    56  列表请求中的帐户。以上几点将继续适用于非基于JSON的响应(“批准”/“拒绝”)。
    57  
    58  */
    59  
    60  
    61  function ApproveListing(request){
    62  	console.log("In js approve listing");
    63  	console.log(request.accounts[3].Address)
    64  	console.log(request.meta.Remote)
    65  	return "Approve"
    66  }
    67  
    68  function ApproveTx(request){
    69  	console.log("test");
    70  	console.log("from");
    71  	return "Reject";
    72  }
    73  
    74  function test(thing){
    75  	console.log(thing.String())
    76  }
    77  
    78  `
    79  
    80  func mixAddr(a string) (*common.MixedcaseAddress, error) {
    81  	return common.NewMixedcaseAddressFromString(a)
    82  }
    83  
    84  type alwaysDenyUI struct{}
    85  
    86  func (alwaysDenyUI) OnSignerStartup(info core.StartupInfo) {
    87  }
    88  
    89  func (alwaysDenyUI) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
    90  	return core.SignTxResponse{Transaction: request.Transaction, Approved: false, Password: ""}, nil
    91  }
    92  
    93  func (alwaysDenyUI) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
    94  	return core.SignDataResponse{Approved: false, Password: ""}, nil
    95  }
    96  
    97  func (alwaysDenyUI) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
    98  	return core.ExportResponse{Approved: false}, nil
    99  }
   100  
   101  func (alwaysDenyUI) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
   102  	return core.ImportResponse{Approved: false, OldPassword: "", NewPassword: ""}, nil
   103  }
   104  
   105  func (alwaysDenyUI) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
   106  	return core.ListResponse{Accounts: nil}, nil
   107  }
   108  
   109  func (alwaysDenyUI) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
   110  	return core.NewAccountResponse{Approved: false, Password: ""}, nil
   111  }
   112  
   113  func (alwaysDenyUI) ShowError(message string) {
   114  	panic("implement me")
   115  }
   116  
   117  func (alwaysDenyUI) ShowInfo(message string) {
   118  	panic("implement me")
   119  }
   120  
   121  func (alwaysDenyUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
   122  	panic("implement me")
   123  }
   124  
   125  func initRuleEngine(js string) (*rulesetUI, error) {
   126  	r, err := NewRuleEvaluator(&alwaysDenyUI{}, storage.NewEphemeralStorage(), storage.NewEphemeralStorage())
   127  	if err != nil {
   128  		return nil, fmt.Errorf("failed to create js engine: %v", err)
   129  	}
   130  	if err = r.Init(js); err != nil {
   131  		return nil, fmt.Errorf("failed to load bootstrap js: %v", err)
   132  	}
   133  	return r, nil
   134  }
   135  
   136  func TestListRequest(t *testing.T) {
   137  	accs := make([]core.Account, 5)
   138  
   139  	for i := range accs {
   140  		addr := fmt.Sprintf("000000000000000000000000000000000000000%x", i)
   141  		acc := core.Account{
   142  			Address: common.BytesToAddress(common.Hex2Bytes(addr)),
   143  			URL:     accounts.URL{Scheme: "test", Path: fmt.Sprintf("acc-%d", i)},
   144  		}
   145  		accs[i] = acc
   146  	}
   147  
   148  	js := `function ApproveListing(){ return "Approve" }`
   149  
   150  	r, err := initRuleEngine(js)
   151  	if err != nil {
   152  		t.Errorf("Couldn't create evaluator %v", err)
   153  		return
   154  	}
   155  	resp, err := r.ApproveListing(&core.ListRequest{
   156  		Accounts: accs,
   157  		Meta:     core.Metadata{Remote: "remoteip", Local: "localip", Scheme: "inproc"},
   158  	})
   159  	if len(resp.Accounts) != len(accs) {
   160  		t.Errorf("Expected check to resolve to 'Approve'")
   161  	}
   162  }
   163  
   164  func TestSignTxRequest(t *testing.T) {
   165  
   166  	js := `
   167  	function ApproveTx(r){
   168  		console.log("transaction.from", r.transaction.from);
   169  		console.log("transaction.to", r.transaction.to);
   170  		console.log("transaction.value", r.transaction.value);
   171  		console.log("transaction.nonce", r.transaction.nonce);
   172  		if(r.transaction.from.toLowerCase()=="0x0000000000000000000000000000000000001337"){ return "Approve"}
   173  		if(r.transaction.from.toLowerCase()=="0x000000000000000000000000000000000000dead"){ return "Reject"}
   174  	}`
   175  
   176  	r, err := initRuleEngine(js)
   177  	if err != nil {
   178  		t.Errorf("Couldn't create evaluator %v", err)
   179  		return
   180  	}
   181  	to, err := mixAddr("000000000000000000000000000000000000dead")
   182  	if err != nil {
   183  		t.Error(err)
   184  		return
   185  	}
   186  	from, err := mixAddr("0000000000000000000000000000000000001337")
   187  
   188  	if err != nil {
   189  		t.Error(err)
   190  		return
   191  	}
   192  	fmt.Printf("to %v", to.Address().String())
   193  	resp, err := r.ApproveTx(&core.SignTxRequest{
   194  		Transaction: core.SendTxArgs{
   195  			From: *from,
   196  			To:   to},
   197  		Callinfo: nil,
   198  		Meta:     core.Metadata{Remote: "remoteip", Local: "localip", Scheme: "inproc"},
   199  	})
   200  	if err != nil {
   201  		t.Errorf("Unexpected error %v", err)
   202  	}
   203  	if !resp.Approved {
   204  		t.Errorf("Expected check to resolve to 'Approve'")
   205  	}
   206  }
   207  
   208  type dummyUI struct {
   209  	calls []string
   210  }
   211  
   212  func (d *dummyUI) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
   213  	d.calls = append(d.calls, "ApproveTx")
   214  	return core.SignTxResponse{}, core.ErrRequestDenied
   215  }
   216  
   217  func (d *dummyUI) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
   218  	d.calls = append(d.calls, "ApproveSignData")
   219  	return core.SignDataResponse{}, core.ErrRequestDenied
   220  }
   221  
   222  func (d *dummyUI) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
   223  	d.calls = append(d.calls, "ApproveExport")
   224  	return core.ExportResponse{}, core.ErrRequestDenied
   225  }
   226  
   227  func (d *dummyUI) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
   228  	d.calls = append(d.calls, "ApproveImport")
   229  	return core.ImportResponse{}, core.ErrRequestDenied
   230  }
   231  
   232  func (d *dummyUI) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
   233  	d.calls = append(d.calls, "ApproveListing")
   234  	return core.ListResponse{}, core.ErrRequestDenied
   235  }
   236  
   237  func (d *dummyUI) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
   238  	d.calls = append(d.calls, "ApproveNewAccount")
   239  	return core.NewAccountResponse{}, core.ErrRequestDenied
   240  }
   241  
   242  func (d *dummyUI) ShowError(message string) {
   243  	d.calls = append(d.calls, "ShowError")
   244  }
   245  
   246  func (d *dummyUI) ShowInfo(message string) {
   247  	d.calls = append(d.calls, "ShowInfo")
   248  }
   249  
   250  func (d *dummyUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
   251  	d.calls = append(d.calls, "OnApprovedTx")
   252  }
   253  func (d *dummyUI) OnSignerStartup(info core.StartupInfo) {
   254  }
   255  
   256  //TestForwarding测试规则引擎是否正确地将请求分派给下一个调用方
   257  func TestForwarding(t *testing.T) {
   258  
   259  	js := ""
   260  	ui := &dummyUI{make([]string, 0)}
   261  	jsBackend := storage.NewEphemeralStorage()
   262  	credBackend := storage.NewEphemeralStorage()
   263  	r, err := NewRuleEvaluator(ui, jsBackend, credBackend)
   264  	if err != nil {
   265  		t.Fatalf("Failed to create js engine: %v", err)
   266  	}
   267  	if err = r.Init(js); err != nil {
   268  		t.Fatalf("Failed to load bootstrap js: %v", err)
   269  	}
   270  	r.ApproveSignData(nil)
   271  	r.ApproveTx(nil)
   272  	r.ApproveImport(nil)
   273  	r.ApproveNewAccount(nil)
   274  	r.ApproveListing(nil)
   275  	r.ApproveExport(nil)
   276  	r.ShowError("test")
   277  	r.ShowInfo("test")
   278  
   279  //这个没有转发
   280  	r.OnApprovedTx(ethapi.SignTransactionResult{})
   281  
   282  	expCalls := 8
   283  	if len(ui.calls) != expCalls {
   284  
   285  		t.Errorf("Expected %d forwarded calls, got %d: %s", expCalls, len(ui.calls), strings.Join(ui.calls, ","))
   286  
   287  	}
   288  
   289  }
   290  
   291  func TestMissingFunc(t *testing.T) {
   292  	r, err := initRuleEngine(JS)
   293  	if err != nil {
   294  		t.Errorf("Couldn't create evaluator %v", err)
   295  		return
   296  	}
   297  
   298  	_, err = r.execute("MissingMethod", "test")
   299  
   300  	if err == nil {
   301  		t.Error("Expected error")
   302  	}
   303  
   304  	approved, err := r.checkApproval("MissingMethod", nil, nil)
   305  	if err == nil {
   306  		t.Errorf("Expected missing method to yield error'")
   307  	}
   308  	if approved {
   309  		t.Errorf("Expected missing method to cause non-approval")
   310  	}
   311  	fmt.Printf("Err %v", err)
   312  
   313  }
   314  func TestStorage(t *testing.T) {
   315  
   316  	js := `
   317  	function testStorage(){
   318  		storage.Put("mykey", "myvalue")
   319  		a = storage.Get("mykey")
   320  
   321  storage.Put("mykey", ["a", "list"])  	//应生成“a,list”
   322  		a += storage.Get("mykey")
   323  
   324  
   325  storage.Put("mykey", {"an": "object"}) 	//应导致“[对象对象]”
   326  		a += storage.Get("mykey")
   327  
   328  
   329  storage.Put("mykey", JSON.stringify({"an": "object"})) //应导致“”an“:”对象“”
   330  		a += storage.Get("mykey")
   331  
   332  a += storage.Get("missingkey")		//缺少键应导致空字符串
   333  storage.Put("","missing key==noop") //无法使用0长度密钥存储
   334  a += storage.Get("")				//应导致“”。
   335  
   336  		var b = new BigNumber(2)
   337  var c = new BigNumber(16)//“0xF0”,16)
   338  		var d = b.plus(c)
   339  		console.log(d)
   340  		return a
   341  	}
   342  `
   343  	r, err := initRuleEngine(js)
   344  	if err != nil {
   345  		t.Errorf("Couldn't create evaluator %v", err)
   346  		return
   347  	}
   348  
   349  	v, err := r.execute("testStorage", nil)
   350  
   351  	if err != nil {
   352  		t.Errorf("Unexpected error %v", err)
   353  	}
   354  
   355  	retval, err := v.ToString()
   356  
   357  	if err != nil {
   358  		t.Errorf("Unexpected error %v", err)
   359  	}
   360  	exp := `myvaluea,list[object Object]{"an":"object"}`
   361  	if retval != exp {
   362  		t.Errorf("Unexpected data, expected '%v', got '%v'", exp, retval)
   363  	}
   364  	fmt.Printf("Err %v", err)
   365  
   366  }
   367  
   368  const ExampleTxWindow = `
   369  	function big(str){
   370  		if(str.slice(0,2) == "0x"){ return new BigNumber(str.slice(2),16)}
   371  		return new BigNumber(str)
   372  	}
   373  
   374  //时间窗口:1周
   375  	var window = 1000* 3600*24*7;
   376  
   377  //极限:1醚
   378  	var limit = new BigNumber("1e18");
   379  
   380  	function isLimitOk(transaction){
   381  		var value = big(transaction.value)
   382  //启动窗口功能
   383  		var windowstart = new Date().getTime() - window;
   384  
   385  		var txs = [];
   386  		var stored = storage.Get('txs');
   387  
   388  		if(stored != ""){
   389  			txs = JSON.parse(stored)
   390  		}
   391  //首先,删除时间窗口之外的所有内容
   392  		var newtxs = txs.filter(function(tx){return tx.tstamp > windowstart});
   393  		console.log(txs, newtxs.length);
   394  
   395  //第二,合计当前总额
   396  		sum = new BigNumber(0)
   397  
   398  		sum = newtxs.reduce(function(agg, tx){ return big(tx.value).plus(agg)}, sum);
   399  		console.log("ApproveTx > Sum so far", sum);
   400  		console.log("ApproveTx > Requested", value.toNumber());
   401  
   402  //我们会超过每周限额吗?
   403  		return sum.plus(value).lt(limit)
   404  
   405  	}
   406  	function ApproveTx(r){
   407  		console.log(r)
   408  		console.log(typeof(r))
   409  		if (isLimitOk(r.transaction)){
   410  			return "Approve"
   411  		}
   412  		return "Nope"
   413  	}
   414  
   415   /*
   416   *OnApprovedTx(str)在交易被批准和签署后调用。参数
   417    *“response_str”包含将发送给外部调用方的返回值。
   418   *此方法的返回值为ignore-进行此回调的原因是允许
   419   *用于跟踪已批准交易的规则集。
   420   *
   421   *在执行速率限制规则时,应使用此回调。
   422   *如果规则的响应既不包含“批准”也不包含“拒绝”,则发送将进入手动处理。如果用户
   423   *然后接受事务,将调用此方法。
   424   *
   425   *tldr;使用此方法跟踪已签名的事务,而不是使用approvetx中的数据。
   426   **/
   427  
   428   	function OnApprovedTx(resp){
   429  		var value = big(resp.tx.value)
   430  		var txs = []
   431  //加载存储的事务
   432  		var stored = storage.Get('txs');
   433  		if(stored != ""){
   434  			txs = JSON.parse(stored)
   435  		}
   436  //将此添加到存储
   437  		txs.push({tstamp: new Date().getTime(), value: value});
   438  		storage.Put("txs", JSON.stringify(txs));
   439  	}
   440  
   441  `
   442  
   443  func dummyTx(value hexutil.Big) *core.SignTxRequest {
   444  
   445  	to, _ := mixAddr("000000000000000000000000000000000000dead")
   446  	from, _ := mixAddr("000000000000000000000000000000000000dead")
   447  	n := hexutil.Uint64(3)
   448  	gas := hexutil.Uint64(21000)
   449  	gasPrice := hexutil.Big(*big.NewInt(2000000))
   450  
   451  	return &core.SignTxRequest{
   452  		Transaction: core.SendTxArgs{
   453  			From:     *from,
   454  			To:       to,
   455  			Value:    value,
   456  			Nonce:    n,
   457  			GasPrice: gasPrice,
   458  			Gas:      gas,
   459  		},
   460  		Callinfo: []core.ValidationInfo{
   461  			{Typ: "Warning", Message: "All your base are bellong to us"},
   462  		},
   463  		Meta: core.Metadata{Remote: "remoteip", Local: "localip", Scheme: "inproc"},
   464  	}
   465  }
   466  func dummyTxWithV(value uint64) *core.SignTxRequest {
   467  
   468  	v := big.NewInt(0).SetUint64(value)
   469  	h := hexutil.Big(*v)
   470  	return dummyTx(h)
   471  }
   472  func dummySigned(value *big.Int) *types.Transaction {
   473  	to := common.HexToAddress("000000000000000000000000000000000000dead")
   474  	gas := uint64(21000)
   475  	gasPrice := big.NewInt(2000000)
   476  	data := make([]byte, 0)
   477  	return types.NewTransaction(3, to, value, gas, gasPrice, data)
   478  
   479  }
   480  func TestLimitWindow(t *testing.T) {
   481  
   482  	r, err := initRuleEngine(ExampleTxWindow)
   483  	if err != nil {
   484  		t.Errorf("Couldn't create evaluator %v", err)
   485  		return
   486  	}
   487  
   488  //0.3乙醚:429D069189E0000 wei
   489  	v := big.NewInt(0).SetBytes(common.Hex2Bytes("0429D069189E0000"))
   490  	h := hexutil.Big(*v)
   491  //前三个应该成功
   492  	for i := 0; i < 3; i++ {
   493  		unsigned := dummyTx(h)
   494  		resp, err := r.ApproveTx(unsigned)
   495  		if err != nil {
   496  			t.Errorf("Unexpected error %v", err)
   497  		}
   498  		if !resp.Approved {
   499  			t.Errorf("Expected check to resolve to 'Approve'")
   500  		}
   501  //创建虚拟签名事务
   502  
   503  		response := ethapi.SignTransactionResult{
   504  			Tx:  dummySigned(v),
   505  			Raw: common.Hex2Bytes("deadbeef"),
   506  		}
   507  		r.OnApprovedTx(response)
   508  	}
   509  //第四个应该失败
   510  	resp, err := r.ApproveTx(dummyTx(h))
   511  	if resp.Approved {
   512  		t.Errorf("Expected check to resolve to 'Reject'")
   513  	}
   514  
   515  }
   516  
   517  //dontcallme用作不希望调用的下一个处理程序-它调用测试失败
   518  type dontCallMe struct {
   519  	t *testing.T
   520  }
   521  
   522  func (d *dontCallMe) OnSignerStartup(info core.StartupInfo) {
   523  }
   524  
   525  func (d *dontCallMe) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
   526  	d.t.Fatalf("Did not expect next-handler to be called")
   527  	return core.SignTxResponse{}, core.ErrRequestDenied
   528  }
   529  
   530  func (d *dontCallMe) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
   531  	d.t.Fatalf("Did not expect next-handler to be called")
   532  	return core.SignDataResponse{}, core.ErrRequestDenied
   533  }
   534  
   535  func (d *dontCallMe) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
   536  	d.t.Fatalf("Did not expect next-handler to be called")
   537  	return core.ExportResponse{}, core.ErrRequestDenied
   538  }
   539  
   540  func (d *dontCallMe) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
   541  	d.t.Fatalf("Did not expect next-handler to be called")
   542  	return core.ImportResponse{}, core.ErrRequestDenied
   543  }
   544  
   545  func (d *dontCallMe) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
   546  	d.t.Fatalf("Did not expect next-handler to be called")
   547  	return core.ListResponse{}, core.ErrRequestDenied
   548  }
   549  
   550  func (d *dontCallMe) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
   551  	d.t.Fatalf("Did not expect next-handler to be called")
   552  	return core.NewAccountResponse{}, core.ErrRequestDenied
   553  }
   554  
   555  func (d *dontCallMe) ShowError(message string) {
   556  	d.t.Fatalf("Did not expect next-handler to be called")
   557  }
   558  
   559  func (d *dontCallMe) ShowInfo(message string) {
   560  	d.t.Fatalf("Did not expect next-handler to be called")
   561  }
   562  
   563  func (d *dontCallMe) OnApprovedTx(tx ethapi.SignTransactionResult) {
   564  	d.t.Fatalf("Did not expect next-handler to be called")
   565  }
   566  
   567  //testcontext清除了规则引擎不在多个请求上保留变量的测试。
   568  //如果是这样,那就不好了,因为开发人员可能会依赖它来存储数据,
   569  //而不是使用基于磁盘的数据存储
   570  func TestContextIsCleared(t *testing.T) {
   571  
   572  	js := `
   573  	function ApproveTx(){
   574  		if (typeof foobar == 'undefined') {
   575  			foobar = "Approve"
   576   		}
   577  		console.log(foobar)
   578  		if (foobar == "Approve"){
   579  			foobar = "Reject"
   580  		}else{
   581  			foobar = "Approve"
   582  		}
   583  		return foobar
   584  	}
   585  	`
   586  	ui := &dontCallMe{t}
   587  	r, err := NewRuleEvaluator(ui, storage.NewEphemeralStorage(), storage.NewEphemeralStorage())
   588  	if err != nil {
   589  		t.Fatalf("Failed to create js engine: %v", err)
   590  	}
   591  	if err = r.Init(js); err != nil {
   592  		t.Fatalf("Failed to load bootstrap js: %v", err)
   593  	}
   594  	tx := dummyTxWithV(0)
   595  	r1, err := r.ApproveTx(tx)
   596  	r2, err := r.ApproveTx(tx)
   597  	if r1.Approved != r2.Approved {
   598  		t.Errorf("Expected execution context to be cleared between executions")
   599  	}
   600  }
   601  
   602  func TestSignData(t *testing.T) {
   603  
   604  	js := `function ApproveListing(){
   605      return "Approve"
   606  }
   607  function ApproveSignData(r){
   608      if( r.address.toLowerCase() == "0x694267f14675d7e1b9494fd8d72fefe1755710fa")
   609      {
   610          if(r.message.indexOf("bazonk") >= 0){
   611              return "Approve"
   612          }
   613          return "Reject"
   614      }
   615  //否则进入手动处理
   616  }`
   617  	r, err := initRuleEngine(js)
   618  	if err != nil {
   619  		t.Errorf("Couldn't create evaluator %v", err)
   620  		return
   621  	}
   622  	message := []byte("baz bazonk foo")
   623  	hash, msg := core.SignHash(message)
   624  	raw := hexutil.Bytes(message)
   625  	addr, _ := mixAddr("0x694267f14675d7e1b9494fd8d72fefe1755710fa")
   626  
   627  	fmt.Printf("address %v %v\n", addr.String(), addr.Original())
   628  	resp, err := r.ApproveSignData(&core.SignDataRequest{
   629  		Address: *addr,
   630  		Message: msg,
   631  		Hash:    hash,
   632  		Meta:    core.Metadata{Remote: "remoteip", Local: "localip", Scheme: "inproc"},
   633  		Rawdata: raw,
   634  	})
   635  	if err != nil {
   636  		t.Fatalf("Unexpected error %v", err)
   637  	}
   638  	if !resp.Approved {
   639  		t.Fatalf("Expected approved")
   640  	}
   641  }