How to create a transaction with a custom script?

15

8

Is there a step-by-step tutorial or any documentation covering how to create a transaction that is not a standard OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG?

It seems very odd that there is absolutely no documentation or information covering how to create a transaction like this, when it is one of Bitcoin's greatest advantages.

Maybe a link to some open-source software which creates custom script transactions would be helpful. I don't know of any that exist off hand though.

bvpx

Posted 2013-10-24T20:57:22.457

Reputation: 1 052

1As long as no "; drop table wallet;" is possible.LateralFractal 2013-10-25T04:52:32.260

1Little Bobby Tables, is that you?!RLH 2013-10-25T17:10:28.790

1

Don't most nodes reject custom scripts? That's what Blockchain.info's "strange transactions" are, right?

KJ O 2013-10-25T20:52:40.833

1

As far as I know, only transactions containing the "disabled" opcodes found here are rejected by nodes: https://en.bitcoin.it/wiki/Script

bvpx 2013-10-25T21:17:52.850

Maybe this Node.js tool can help https://github.com/jgarzik/txtool

Jonas Oestman 2013-10-31T05:03:04.113

have a look at bitcore-libBadr Bellaj 2017-08-26T09:05:52.650

Answers

3

I would suggest using Python to accomplish this. pybitcointools have what you need to be able to deserialize a hex transaction to JSON, and manipulate that and then serialize again to be able to sign and broadcast via support for blockchain.info.

This example will rebuild the standard script from the ground up:

>>> opdup = 0x76
>>> ophash160 = 0xA9
>>> push20 = 0x14
>>> opeqver = 0x88
>>> opchecksig = 0xAC
>>> pubkeyhash = 0x2dbde30815faee5bf221d6688ebad7e12f7b2b1a

We are going to append hex values by moving them bitwise.

  • OP_DUP OP_HASH160 2dbde30815faee5bf221d6688ebad7e12f7b2b1a OP_EQUALVERIFY OP_CHECKSIG
  • This is the hex we want 76a9142dbde30815faee5bf221d6688ebad7e12f7b2b1a88ac

This is one way of doing it

>>> quickfix = 0xff
>>> asm = quickfix
>>> asm = asm << 8 | opdup
>>> asm = asm << 8 | ophash160
>>> asm = asm << 8 | push20
>>> asm = asm << 8*20 | pubkeyhash
>>> asm = asm << 8 | opeqver
>>> asm = asm << 8 | opchecksig

Ant then to check if its the same:

>>> almost = hex(asm)
>>> ready = almost.partition("0xff")[2]
>>> print(ready)

Hope this is what you are after :-)

Jonas Oestman

Posted 2013-10-24T20:57:22.457

Reputation: 474

there is a bug if 0x00 (OP_FALSE) is used, if we try to left shift that nothing will happen. a quick fix is to add 0xff first, and then remove it at the last stepJonas Oestman 2013-11-03T17:41:28.910

1

ABSOLUTELY Go!

import(
    "github.com/btcsuite/btcd/txscript"
    "github.com/btcsuite/btcd/wire"
)

tx := wire.NewMsgTx(2)
tx.AddTxOut(wire.NewTxOut(int64(*outputvalueFlag*1e8), script()))

func script() ([]byte) {
    script := txscript.NewScriptBuilder()
    script.AddInt64(1)
    script.AddData(bytes[0:65])
    script.AddInt64(1)
    script.AddOp(txscript.OP_CHECKMULTISIG)
    return script.Script()
}
...

MCCCS

Posted 2013-10-24T20:57:22.457

Reputation: 5 827