github.com/turingchain2020/turingchain@v1.1.21/executor/allow.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package executor
     6  
     7  import (
     8  	"bytes"
     9  
    10  	"github.com/pkg/errors"
    11  
    12  	drivers "github.com/turingchain2020/turingchain/system/dapp"
    13  	"github.com/turingchain2020/turingchain/types"
    14  )
    15  
    16  func isAllowKeyWrite(e *executor, key, realExecer []byte, tx *types.Transaction, index int) bool {
    17  	keyExecer, err := types.FindExecer(key)
    18  	if err != nil {
    19  		elog.Error("find execer ", "err", err, "key", string(key), "keyexecer", string(keyExecer))
    20  		return false
    21  	}
    22  	//平行链中 user.p.guodun.xxxx -> 实际上是 xxxx
    23  	//注意: user.p.guodun.user.evm.hash -> user.evm.hash 而不是 evm
    24  	cfg := e.api.GetConfig()
    25  	exec := cfg.GetParaExec(tx.Execer)
    26  	//默认规则1: (执行器只能修改执行器自己内部的数据)
    27  	if bytes.Equal(keyExecer, exec) {
    28  		return true
    29  	}
    30  	// 历史原因做只针对对turingchaincoin的fork特殊化处理一下
    31  	// manage 的key 是 config
    32  	// token 的部分key 是 mavl-create-token-
    33  	if !cfg.IsFork(e.height, "ForkExecKey") {
    34  		if bytes.Equal(exec, []byte("manage")) && bytes.Equal(keyExecer, []byte("config")) {
    35  			return true
    36  		}
    37  		if bytes.Equal(exec, []byte("token")) {
    38  			if bytes.HasPrefix(key, []byte("mavl-create-token-")) {
    39  				return true
    40  			}
    41  		}
    42  	}
    43  	//每个合约中,都会开辟一个区域,这个区域是另外一个合约可以修改的区域
    44  	//我们把数据限制在这个位置,防止合约的其他位置被另外一个合约修改
    45  	//  execaddr 是加了前缀生成的地址, 而参数 realExecer 是没有前缀的执行器名字
    46  	keyExecAddr, ok := types.GetExecKey(key)
    47  	if ok && keyExecAddr == drivers.ExecAddress(string(tx.Execer)) {
    48  		return true
    49  	}
    50  	//对应上面两种写权限,调用真实的合约,进行判断:
    51  	//执行器会判断一个合约是否可以 被另一个合约写入
    52  	execdriver := keyExecer
    53  	if ok && keyExecAddr == drivers.ExecAddress(string(realExecer)) {
    54  		//判断user.p.xxx.token 是否可以写 token 合约的内容之类的
    55  		execdriver = realExecer
    56  	}
    57  	//此处loadDriver比较特殊,传入了空交易和当前交易的index
    58  	//主要为了内部driver.Allow可能会基于index进行逻辑判断,如挖矿交易限定只能是区块的第一笔交易
    59  	c := e.loadDriver(&types.Transaction{Execer: execdriver}, index)
    60  	//交给 -> friend 来判定
    61  	return c.IsFriend(execdriver, key, tx)
    62  }
    63  
    64  func isAllowLocalKey(cfg *types.TuringchainConfig, execer []byte, key []byte) error {
    65  	err := isAllowLocalKey2(cfg, execer, key)
    66  	if err != nil {
    67  		realexec := types.GetRealExecName(execer)
    68  		if !bytes.Equal(realexec, execer) {
    69  			err2 := isAllowLocalKey2(cfg, realexec, key)
    70  			err = errors.Wrapf(err2, "1st check err: %s. 2nd check err", err.Error())
    71  		}
    72  		if err != nil {
    73  			elog.Error("isAllowLocalKey failed", "err", err.Error())
    74  			return errors.Cause(err)
    75  		}
    76  
    77  	}
    78  	return nil
    79  }
    80  
    81  func isAllowLocalKey2(cfg *types.TuringchainConfig, execer []byte, key []byte) error {
    82  	if len(execer) < 1 {
    83  		return errors.Wrap(types.ErrLocalPrefix, "execer empty")
    84  	}
    85  	minkeylen := len(types.LocalPrefix) + len(execer) + 2
    86  	if len(key) <= minkeylen {
    87  		err := errors.Wrapf(types.ErrLocalKeyLen, "isAllowLocalKey too short. key=%s exec=%s", string(key), string(execer))
    88  		return err
    89  	}
    90  	if key[minkeylen-1] != '-' || key[len(types.LocalPrefix)] != '-' {
    91  		err := errors.Wrapf(types.ErrLocalPrefix,
    92  			"isAllowLocalKey prefix last char or separator is not '-'. key=%s exec=%s minkeylen=%d title=%s",
    93  			string(key), string(execer), minkeylen, cfg.GetTitle())
    94  		return err
    95  	}
    96  	if !bytes.HasPrefix(key, types.LocalPrefix) {
    97  		err := errors.Wrapf(types.ErrLocalPrefix, "isAllowLocalKey common prefix not match. key=%s exec=%s",
    98  			string(key), string(execer))
    99  		return err
   100  	}
   101  	if !bytes.HasPrefix(key[len(types.LocalPrefix)+1:], execer) {
   102  		err := errors.Wrapf(types.ErrLocalPrefix, "isAllowLocalKey key prefix not match. key=%s exec=%s",
   103  			string(key), string(execer))
   104  		return err
   105  	}
   106  	return nil
   107  }