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  }