| 387 | |
| 388 | # This is used, eg, for blockchain heights in coinbase scripts (bip34) |
| 389 | class CScriptNum: |
| 390 | __slots__ = ("value",) |
| 391 | |
| 392 | def __init__(self, d=0): |
| 393 | self.value = d |
| 394 | |
| 395 | @staticmethod |
| 396 | def encode(obj): |
| 397 | r = bytearray(0) |
| 398 | if obj.value == 0: |
| 399 | return bytes(r) |
| 400 | neg = obj.value < 0 |
| 401 | absvalue = -obj.value if neg else obj.value |
| 402 | while (absvalue): |
| 403 | r.append(absvalue & 0xff) |
| 404 | absvalue >>= 8 |
| 405 | if r[-1] & 0x80: |
| 406 | r.append(0x80 if neg else 0) |
| 407 | elif neg: |
| 408 | r[-1] |= 0x80 |
| 409 | return bytes([len(r)]) + r |
| 410 | |
| 411 | @staticmethod |
| 412 | def decode(vch): |
| 413 | result = 0 |
| 414 | # We assume valid push_size and minimal encoding |
| 415 | value = vch[1:] |
| 416 | if len(value) == 0: |
| 417 | return result |
| 418 | for i, byte in enumerate(value): |
| 419 | result |= int(byte) << 8 * i |
| 420 | if value[-1] >= 0x80: |
| 421 | # Mask for all but the highest result bit |
| 422 | num_mask = (2**(len(value) * 8) - 1) >> 1 |
| 423 | result &= num_mask |
| 424 | result *= -1 |
| 425 | return result |
| 426 | |
| 427 | |
| 428 | class CScript(bytes): |
no outgoing calls