github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/vm/splice.go (about) 1 package vm 2 3 import ( 4 "github.com/holiman/uint256" 5 6 "github.com/bytom/bytom/math/checked" 7 ) 8 9 func opCat(vm *virtualMachine) error { 10 if err := vm.applyCost(4); err != nil { 11 return err 12 } 13 14 b, err := vm.pop(true) 15 if err != nil { 16 return err 17 } 18 19 a, err := vm.pop(true) 20 if err != nil { 21 return err 22 } 23 24 lens := int64(len(a) + len(b)) 25 if err = vm.applyCost(lens); err != nil { 26 return err 27 } 28 29 vm.deferCost(-lens) 30 return vm.pushDataStack(append(a, b...), true) 31 } 32 33 func opSubstr(vm *virtualMachine) error { 34 if err := vm.applyCost(4); err != nil { 35 return err 36 } 37 38 sizeBigInt, err := vm.popBigInt(true) 39 if err != nil { 40 return err 41 } 42 43 size, err := bigIntInt64(sizeBigInt) 44 if err != nil { 45 return err 46 } 47 48 if err = vm.applyCost(size); err != nil { 49 return err 50 } 51 52 vm.deferCost(-size) 53 offsetBigInt, err := vm.popBigInt(true) 54 if err != nil { 55 return err 56 } 57 58 offset, err := bigIntInt64(offsetBigInt) 59 if err != nil { 60 return err 61 } 62 63 str, err := vm.pop(true) 64 if err != nil { 65 return err 66 } 67 68 end, ok := checked.AddInt64(offset, size) 69 if !ok || end > int64(len(str)) { 70 return ErrBadValue 71 } 72 73 return vm.pushDataStack(str[offset:end], true) 74 } 75 76 func opLeft(vm *virtualMachine) error { 77 if err := vm.applyCost(4); err != nil { 78 return err 79 } 80 81 sizeBigInt, err := vm.popBigInt(true) 82 if err != nil { 83 return err 84 } 85 86 size, err := bigIntInt64(sizeBigInt) 87 if err != nil { 88 return err 89 } 90 91 if err = vm.applyCost(size); err != nil { 92 return err 93 } 94 95 vm.deferCost(-size) 96 str, err := vm.pop(true) 97 if err != nil { 98 return err 99 } 100 101 if size > int64(len(str)) { 102 return ErrBadValue 103 } 104 105 return vm.pushDataStack(str[:size], true) 106 } 107 108 func opRight(vm *virtualMachine) error { 109 if err := vm.applyCost(4); err != nil { 110 return err 111 } 112 113 sizeBigInt, err := vm.popBigInt(true) 114 if err != nil { 115 return err 116 } 117 118 size, err := bigIntInt64(sizeBigInt) 119 if err != nil { 120 return err 121 } 122 123 if err = vm.applyCost(size); err != nil { 124 return err 125 } 126 127 vm.deferCost(-size) 128 str, err := vm.pop(true) 129 if err != nil { 130 return err 131 } 132 133 lstr := int64(len(str)) 134 if size > lstr { 135 return ErrBadValue 136 } 137 138 return vm.pushDataStack(str[lstr-size:], true) 139 } 140 141 func opSize(vm *virtualMachine) error { 142 if err := vm.applyCost(1); err != nil { 143 return err 144 } 145 146 str, err := vm.top() 147 if err != nil { 148 return err 149 } 150 151 return vm.pushBigInt(uint256.NewInt(uint64(len(str))), true) 152 } 153 154 func opCatpushdata(vm *virtualMachine) error { 155 if err := vm.applyCost(4); err != nil { 156 return err 157 } 158 159 b, err := vm.pop(true) 160 if err != nil { 161 return err 162 } 163 164 a, err := vm.pop(true) 165 if err != nil { 166 return err 167 } 168 169 lens := int64(len(a) + len(b)) 170 if err = vm.applyCost(lens); err != nil { 171 return err 172 } 173 174 vm.deferCost(-lens) 175 return vm.pushDataStack(append(a, PushDataBytes(b)...), true) 176 }