GithubHelp home page GithubHelp logo

aureleoules / bitcandle Goto Github PK

View Code? Open in Web Editor NEW
15.0 5.0 2.0 66 KB

Store data on Bitcoin for 350 sats/KB up to 185 KB by using P2SH-P2WSH witness scripts

License: MIT License

Dockerfile 1.31% Go 98.69%
bitcoin p2sh-p2wsh data-storage segwit

bitcandle's Introduction

Bitcandle

Store data on Bitcoin for 350 sats/KB up to 185 kB by using P2SH-P2WSH witness scripts.

225ed8bc432d37cf434f80717286fd5671f676f12b573294db72a2a8f9b1e7ba

Disclaimer

Storing data on Bitcoin is a controversial subject as it bloats the blockchain with somewhat unnecessary data.
I built this tool to show that there exists an efficient method of storing data: P2SH-P2WSH, lesser known than standard P2PKH / P2PK / OP_RETURN methods.

Cost

Before injecting data we need to create P2SH-P2WSH UTXOs. This can be done in a single transaction, sent by the user, by sending coins to many outputs.
To spend the P2SH-P2WSH UTXOs (injecting data), it costs roughly 0.00000349 BTC per KB. (1 sat/B fee rate).
This is about 84 times cheaper than the P2PKH injection method.

It is obviously free to retrieve data.

Usage

Usage:
  bitcandle [flags]
  bitcandle [command]

Available Commands:
  help        Help about any command
  inject      Inject a file on the Bitcoin network
  retrieve    Retrieve a file on the Bitcoin network

Flags:
  -h, --help   help for bitcandle

Use "bitcandle [command] --help" for more information about a command.

Example

Inject data

$ ./bitcandle inject \
    --fee 1 \
    --file ./image.jpg \
    --network mainnet \
    --change-address bc1q8sl9tnvnuc8z7q80u9wffdf9ugt4arrp6vlamg

✔ Loaded 4556 bytes to inject.
✔ Loaded existing private key.
✔ Connected to electrum server (blockstream.info:110).
ℹ Estimated injection cost: 0.00002176 BTC.
ℹ You must send 0.00002176 BTC to 33z4X8jkMd8WCzhrfgEigzgLyrap1ACWUE.
█████████████████████████████████████████
█████████████████████████████████████████
████ ▄▄▄▄▄ ██▀▄███▀  ▀▄ ▀ ▄ ▀█ ▄▄▄▄▄ ████
████ █   █ █▄▀█▄▀▀▄ ▀█▀▄▀█▀▀██ █   █ ████
████ █▄▄▄█ ██▄▀▀ ▄       █ ▀▀█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█ █▄▀▄█▄▀▄▀ ▀ ▀ █ █▄▄▄▄▄▄▄████
████▄ ▄▀  ▄  ▀█▀ ▀███▄█▀ ▄▀█   ███ ▀▀████
████ ▀ ▄ █▄█ ▀ ▄ ▀ █▄ ▀▀▀ ▄█ █▀▀▀▄█▄ ████
████▄▄▄▀██▄▀ █  ██ ██ ▀▀▀ ██  ▄██▀▀▀ ████
█████▀ ▀▀▄▄▀ ▄▀▀█▄█▀▄▀▀█▀ ▀█▄▄█▀ ▄▄ ▄████
████▄▄ █▄▀▄▀▀█ ▀ ▀███▄█▀▀███▀   ██▀▄ ████
████▄▀▀▄ ▀▄███▀▄ ▀ ▀▄ ███▀█▀▄ ▄▀ ▀█▄▄████
████▄▄▄▀ ▀▄▀█▀█ ██ ██ ▀▀ ▄▀▄ █ ▄▄ ▀▀▀████
████▄▀▀▄ ▄▄▀  █▀█▄█▀▄▀█▀█▀ █▄▀██▄▀█  ████
████▄█▄███▄▄ █▄▀ ▀███▄ ▀  ▀▄ ▄▄▄  █▀ ████
████ ▄▄▄▄▄ █ ██▄ ▀ ▀▄▀▀▀█ ▄▄ █▄█  █ ▄████
████ █   █ █▄   ██ ██  ██ ██ ▄▄▄  █▄▀████
████ █▄▄▄█ █ █▀▀█▄██ ▀▄▀▄▀ ▀▄▄▄▀ ▄█▀▄████
████▄▄▄▄▄▄▄█▄█▄█▄██▄▄▄▄██▄█▄▄▄███▄█▄▄████
█████████████████████████████████████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
✔ Payment received. (1/1)
✔ All payments received.
✔ Data injected.
ℹ TxID: 225ed8bc432d37cf434f80717286fd5671f676f12b573294db72a2a8f9b1e7ba

Retrieve data

$ ./bitcandle retrieve \
    --tx 225ed8bc432d37cf434f80717286fd5671f676f12b573294db72a2a8f9b1e7ba \
    --network mainnet \
    -o /tmp/image.jpg

✔ Connected to electrum server (blockstream.info:110).
✔ Retrieved file.
✔ Saved file to "/tmp/image.jpg".

Docker

$ mkdir data
$ cp ~/Downloads/image.jpg ./data/
$ docker run -it --rm -v $PWD/data:/data aureleoules/bitcandle inject -f ./image.jpg [args]
...
$ docker run -it --rm -v $PWD/data:/data aureleoules/bitcandle retrieve [args]
...

Working example

$ docker run -it --rm -v $PWD/data:/data aureleoules/bitcandle \
    retrieve \
    --tx 225ed8bc432d37cf434f80717286fd5671f676f12b573294db72a2a8f9b1e7ba \
    -o /data/image.jpg

How it works

This tool uses witness scripts in P2SH-P2WSH inputs to store data.
Instead of storing data in the transaction outputs like standard approaches such as P2PKH, P2PK or OP_RETURN, this tool stores data in the transaction inputs (witness).

Witness script

We need to create a new P2SH-P2WSH UTXO. To do that we need to create a witness script.
The script needs to look like this:

  • OP_HASH160
  • OP_PUSHDATA [CHUNK 3 HASH]
  • OP_EQUALVERIFY
  • OP_HASH160
  • OP_PUSHDATA [CHUNK 2 HASH]
  • OP_EQUALVERIFY
  • OP_HASH160
  • OP_PUSHDATA [CHUNK 1 HASH]
  • OP_EQUALVERIFY
  • OP_PUSHDATA [PUBKEY]
  • OP_CHECKSIG

This witness script is hashed and wrapped in a P2SH-P2WSH output script to create a P2SH-P2WSH address such as: 3N9fEcf9yUSspvUc78cQQVJDQi5NkgrHtLQ.

The user must send enough funds to this address so that this UTXO can be spent.

Hashes of chunks are pushed on the stack in order to ensure data integrity.
Once we spend this UTXO, at attacker could scramble chunks of data and the transaction would this be valid if these op codes were not added.

We must also add the PUBKEY and the CHECKSIG op code so that transactions outputs are signed. This prevents attackers from redirecting the output change to another change address. This may not be necessary for small change amounts (minimum on mainnet is 546 sats) but it is recommended as it makes sure the transaction id does not change while the transaction is in the mempool.

This witness script ensures data integrity and prevents output sniping.

Witness data

In order to spend the UTXO and essentially store the file, we must include witness data that unlocks the witness script built previously.
It looks something like this:

  • [SIG]
  • [CHUNK 1]
  • [CHUNK 2]
  • [CHUNK 3]
  • [witness script hex]

This is not a script, this is simply a stack of data. It can only fit 99 chunks of 80 bytes of data.
For larger files, multiple UTXOs must be created using different witness scripts.

Notes

Witness scripts are built deterministically such that for the same file and same public key, the P2SH-P2WSH addresses will remain the same. This may help easily retrieving any stuck funds if needed.
Not a single satoshi is burned in the data injection process. This is a clear advantage compared to other known injection methods like P2PKH. All the fees go back to miners and the change is sent to the address specified.

Use cases

This software can be useful to

  • store censorship resistant documents
  • store pictures of loved ones we wish to remember forever
  • store documents publicly and permanently accessible

License

MIT - Aurèle Oulès

bitcandle's People

Contributors

aureleoules avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.