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 }