def signature_form_segwit(self, i, hashcode=SIGHASH.ALL): """Segwit version of signature_form""" # https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification tx = deepcopy(self) ref = tx.inputs[i].ref() nversion = tx._version[::-1] hashprevouts = sha256(sha256(concat((inp.outpoint() for inp in tx.inputs)))) if not hashcode.is_anyonecanpay() else pad(0, 32) hashsequence = sha256(sha256(concat(inp._sequence[::-1] for inp in tx.inputs))) if hashcode == SIGHASH.ALL else pad(0, 32) outpoint = tx.inputs[i].outpoint() scriptcode = serialize(tx.inputs[i].scriptcode()) value = ref._value[::-1] nsequence = tx.inputs[i]._sequence[::-1] if not (hashcode.is_single() or hashcode.is_none()): hashoutputs = sha256(sha256(concat(out._value[::-1] + push(out.script) for out in tx.outputs))) elif hashcode.is_single() and i < len(tx.outputs): hashoutputs = sha256(sha256(tx.outputs[i]._value[::-1] + push(tx.outputs[i].script))) else: hashoutputs = pad(0, 32) nlocktime = tx._lock_time[::-1] sighash = pad(hashcode.value, 4)[::-1] return concat([nversion, hashprevouts, hashsequence, outpoint, scriptcode, value, nsequence, hashoutputs, nlocktime, sighash])
def signature_form_legacy(self, i, script=b'', hashcode=SIGHASH.ALL): """Create the object to be signed for the i-th input of this transaction""" # Recreates the object that needs to be signed which is not the actual transaction # More info at: # https://bitcoin.stackexchange.com/questions/32628/redeeming-a-raw-transaction-step-by-step-example-required/32695#32695 # https://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx # https://rya.nc/sartre.html # https://bitcoin.stackexchange.com/questions/41209/how-to-sign-a-transaction-with-multiple-inputs # https://en.bitcoin.it/wiki/OP_CHECKSIG tx = deepcopy(self) # the input references a previous output from which we need the scriptPubKey script = script or tx.inputs[i].ref().script for input in tx.inputs: input.script = b'' tx.inputs[i].script = script # https://en.bitcoin.it/wiki/OP_CHECKSIG if hashcode == SIGHASH.NONE: tx.outputs = [] elif hashcode == SIGHASH.SINGLE: tx.outputs = tx.outputs[:len(tx.inputs)] for output in tx.outputs: output.script = b'' output.value = 2**64 - 1 for idx, input in enumerate(tx.inputs): if not idx == i: input.sequence = 0 elif hashcode == SIGHASH.ANYONECANPAY: tx.inputs = [tx.inputs[i]] return tx.serialize(segwit=tx.inputs[i].segwit) + pad(hashcode.value, 4)[::-1]
def index(self, x): self._index = pad(x, 4)
def sequence(self, x): self._sequence = pad(x, 4)
def value(self, x): self._value = pad(x, 8)