{"id":13810875,"url":"https://github.com/ethereum/btcrelay","last_synced_at":"2025-11-01T19:30:28.230Z","repository":{"id":33599041,"uuid":"37251187","full_name":"ethereum/btcrelay","owner":"ethereum","description":"Ethereum contract for Bitcoin SPV: Live on https://etherscan.io/address/0x41f274c0023f83391de4e0733c609df5a124c3d4","archived":false,"fork":false,"pushed_at":"2023-07-03T14:50:50.000Z","size":61750,"stargazers_count":617,"open_issues_count":25,"forks_count":412,"subscribers_count":61,"default_branch":"develop","last_synced_at":"2025-02-10T15:07:26.049Z","etag":null,"topics":["bitcoin","bitcoin-proof","bitcoin-transaction","btc-relay","ethereum","live","mainnet","production","smart-contracts","solidity"],"latest_commit_sha":null,"homepage":"http://btcrelay.org","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ethereum.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-06-11T09:14:47.000Z","updated_at":"2025-02-09T13:13:36.000Z","dependencies_parsed_at":"2024-09-24T13:38:00.980Z","dependency_job_id":null,"html_url":"https://github.com/ethereum/btcrelay","commit_stats":{"total_commits":1408,"total_committers":4,"mean_commits":352.0,"dds":"0.0028409090909090606","last_synced_commit":"3cdf41a87750bfcc2ea62cb2c5d693fd71bdd47f"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Fbtcrelay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Fbtcrelay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Fbtcrelay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Fbtcrelay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ethereum","download_url":"https://codeload.github.com/ethereum/btcrelay/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239318936,"owners_count":19619502,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitcoin","bitcoin-proof","bitcoin-transaction","btc-relay","ethereum","live","mainnet","production","smart-contracts","solidity"],"created_at":"2024-08-04T03:00:30.824Z","updated_at":"2025-11-01T19:30:28.130Z","avatar_url":"https://github.com/ethereum.png","language":"Python","funding_links":[],"categories":["Python","Uncategorized","Projects"],"sub_categories":["Uncategorized","Light Clients - SPV"],"readme":"# [BTC Relay](http://btcrelay.org)\n\n[![Join the chat at https://gitter.im/ethereum/btcrelay](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/btcrelay)\n\n[BTC Relay](http://btcrelay.org) is an Ethereum contract for Bitcoin SPV.  The main functionality it provides are:\n\n1. verification of a Bitcoin transaction\n1. optionally relay the Bitcoin transaction to any Ethereum contract\n1. storage of Bitcoin block headers\n1. inspection of the latest Bitcoin block header stored in the contract\n\n## BTC Relay contract address and ABI:\n\n* [mainnet](http://btcrelay.surge.sh/mainnetStatus.html)\n* [testnet Morden](http://btcrelay.surge.sh/testnetContractStatus.html)\n\nThe address and ABI is all that's needed to use BTC Relay, in addition to the API documentation below.\n\n## API\n\n\n##### verifyTx(rawTransaction, transactionIndex, merkleSibling, blockHash)\n\nVerifies the presence of a transaction on the Bitcoin blockchain, primarily that the transaction is on Bitcoin's main chain and has at least 6 confirmations.\n\n* `rawTransaction` - raw `bytes` of the transaction\n* `transactionIndex` - transaction's index within the block, as `int256`\n* `merkleSibling` - array of the sibling hashes comprising the Merkle proof, as `int256[]`\n* `blockHash` - hash of the block that contains the transaction, as `int256`\n\nReturns `uint256`\n* hash of the verified Bitcoin transaction\n* `0` if `rawTransaction` is exactly 64 bytes in length or fails verification\n\n*Note:* See [examples/sampleCall.html](examples/sampleCall.html) including use of [bitcoin-proof](https://www.npmjs.com/package/bitcoin-proof) for constructing `merkleSibling`.\n\n---\n\n##### relayTx(rawTransaction, transactionIndex, merkleSibling, blockHash, contractAddress)\n\nVerifies a Bitcoin transaction per `verifyTx()` and relays the verified transaction to the specified Ethereum contract.\n\n* `rawTransaction` - raw `bytes` of the transaction\n* `transactionIndex` - transaction's index within the block, as `int256`\n* `merkleSibling` - array of the sibling hashes comprising the Merkle proof, as `int256[]`\n* `blockHash` - hash of the block that contains the transaction, as `int256`\n* `contractAddress` - address of the processor contract that will receive the verified Bitcoin transaction, as `int256`\n\nThe processor contract at `contractAddress` should have a function of signature\n`processTransaction(bytes rawTransaction, uint256 transactionHash) returns (int256)`\nand is what will be invoked by `relayTx` if the transaction passes\nverification.  For examples, see\n[BitcoinProcessor.sol](examples/BitcoinProcessor.sol)\nand [testnetSampleRelayTx.html](examples/testnetSampleRelayTx.html).\n\nReturns `int256`\n* value returned by the processor contract's `processTransaction` function\n* or ERR_RELAY_VERIFY, see [constants.se](constants.se)\n\nNote: Callers cannot be 100% certain when an ERR_RELAY_VERIFY occurs because\nit may also have been returned by processTransaction().  Callers should be\naware of the contract that they are relaying transactions to, and\nunderstand what the processor contract's processTransaction method returns.\n\n----\n\n##### storeBlockHeader(blockHeader)\n\nStore a single block header if it is valid, such as a valid Proof-of-Work and the previous block it reference exists.\n\n* `blockHeader` - raw `bytes` of the block header (not the hex string, but the actual bytes).\n\nReturns `int256`\n* block height of the header if it was successfully stored\n* `0` otherwise\n\n----\n\n##### bulkStoreHeader(bytesOfHeaders, numberOfHeaders)\n\nStore multiple block headers if they are valid.\n\n* `bytesOfHeaders` - raw `bytes` of the block headers (not the hex string, but the actual bytes), with one following immediately the other.\n* `numberOfHeaders` - `int256` count of the number of headers being stored.\n\nReturns `int256`\n* block height of the last header if all block headers were successfully stored\n* `0` if any of the block headers were not successfully stored\n\n*Note:* See [deploy/relayTest/testBulkDeploy.yaml](deploy/relayTest/testBulkDeploy.yaml) for an example of the data for storing multiple headers.  Also, to avoid exceeding Ethereum's block gas limit, a guideline is to store only 5 headers at time.\n\n----\n\n##### getBlockHeader(blockHash)\n\nGet the 80 byte block header for a given `blockHash`.  A payment value of\n`getFeeAmount(blockHash)` must be provided in the transaction.\n\n* `blockHash` - hash of the block as `int256`\n\nReturns `bytes`\n* block header, always as 80 bytes (all zeros if header does not exist)\n* or `0` (as a single byte) if insufficient payment is provided\n\n----\n\n##### getBlockHash(blockHeight)\n\nGet the block hash for a given `blockHeight`.\n\n* `blockHeight` - height of the block as `int256`.  Minimum value is `1`.\n\nReturns `int256`\n* block hash\n* `0` if not found\n\n----\n\n##### getAverageChainWork()\n\nReturns the difference between the chainWork of the latest block and the\n10th block prior.\n\nThis is provided in case an Ethereum contract wants to use the chainWork\nor Bitcoin network difficulty (which can be derived) as a data feed.\n\n----\n\n##### getBlockchainHead(), getLastBlockHeight(), others\n\n`getBlockchainHead` - returns the hash of the latest block, as`int256`\n\n`getLastBlockHeight` - returns the block height of the latest block, as `int256`\n\nSee [BitcoinRelayAbi.js](examples/BitcoinRelayABI.js) for other APIs and [testnetContractStatus.html](examples/testnetContractStatus.html) for an example of calling some of them.\n\n----\n\n##### Incentives\n\nThe following APIs are described in `Incentives for Relayers` below.\n\n`storeBlockWithFee()`, `changeFeeRecipient()`, `getFeeRecipient()`, `getFeeAmount()`, `getChangeRecipientFee()`\n\n----\n\n## Examples\n\n[Examples](https://github.com/ethereum/btcrelay/tree/master/examples) for how to use BTC Relay include:\n\n* [testnetSampleCall.html](http://btcrelay.surge.sh/testnetSampleCall.html) for calling [`verifyTx`](#verifytxrawtransaction-transactionindex-merklesibling-blockhash) including use of [bitcoin-proof](https://www.npmjs.com/package/bitcoin-proof) for constructing `merkleSibling`.\n\n* mainnet [sampleCall.html](http://btcrelay.surge.sh/sampleCall.html) for calling [`verifyTx`](#verifytxrawtransaction-transactionindex-merklesibling-blockhash)\n(very similar to above.)\n\n* [testnetSampleRelayTx.html](http://btcrelay.surge.sh/testnetSampleRelayTx.html) shows [`relayTx`](#relaytxrawtransaction-transactionindex-merklesibling-blockhash-contractaddress) relaying a Bitcoin transaction from the frontend to an Ethereum contract.\n\n* [testnetContractStatus.html](examples/testnetContractStatus.html) for calling other basic functions.\n\n----\n\n## How to use BTC Relay\n\nThe easiest way to use BTC Relay is via [`relayTx`](#relaytxrawtransaction-transactionindex-merklesibling-blockhash-contractaddress) because the ABI can remain on the frontend.\n\n[testnetSampleRelayTx.html](http://btcrelay.surge.sh/testnetSampleRelayTx.html) shows how a Bitcoin transaction from the frontend can be passed (relayed) to an Ethereum contract.\n\nSee other [examples](#examples) for other ways to use BTC Relay and the\n[docs for FAQ.](http://btc-relay.readthedocs.io)\n\n### Libs/utils\n\nThanks to those who wrote these:\n\n* https://github.com/rainbeam/solidity-btc-parser\n* https://github.com/tjade273/BTCRelay-tools\n* https://github.com/MrChico/verifyIPFS/blob/master/contracts/verifyIPFS.sol (hex to base58)\n\n----\n\n## Incentives for Relayers\n\nRelayers are those who submit block headers to BTC Relay.  To incentivize the community\nto be relayers, and thus allow BTC Relay to be autonomous and up-to-date with the\nBitcoin blockchain, Relayers can call `storeBlockWithFee`.  The Relayer will be the\n`getFeeRecipient()` for the block they submit, and when any transactions are verified\nin the block, or the header is retrieved via `getBlockHeader`, the Relayer will be\n rewarded with `getFeeAmount()`.\n\n[To avoid a relayer R1 from setting excessive fees](http://btc-relay.readthedocs.io/en/latest/frequently-asked-questions.html#what-prevents-fees-from-being-too-high), it is possible for a relayer R2\nto `changeFeeRecipient()`.  R2 must specify a fee lower than what R1 specified, and\npay `getChangeRecipientFee()` to R1, but now R2 will be the `getFeeRecipient()` for the block\nand will earn all future `getFeeAmount()`.\n\nWith this background, here are API details for incentives.\n\n##### storeBlockWithFee(blockHeader, fee)\n\nStore a single block header (like `storeBlockHeader`) and\nset a fee that will be charged for verifications that use `blockHeader`.\n\n* `blockHeader` - raw `bytes` of the block header (not the hex string, but the actual bytes).\n* `fee` - `int256` amount in wei.\n\nReturns `int256`\n* block height of the header if it was successfully stored\n* `0` otherwise\n\n----\n\n##### changeFeeRecipient(blockHash, fee, recipient)\n\nSet the `fee` and `recipient` for a given `blockHash`.  The call must have `msg.value`\nof at least `getChangeRecipientFee()`, and must also specify a `fee` lower than\nthe current `getFeeAmount(blockHash)`.\n\n* `blockHash` - hash of the block as `int256`.\n* `fee` - `int256` amount in wei.\n* `recipient` - `int256` address of the recipient of fees.\n\nReturns `int256`\n* `1` if the fee and recipient were successfully set\n* `0` otherwise\n\n----\n\n##### getFeeRecipient(blockHash)\n\nGet the address that receives the fees for a given `blockHash`.\n\n* `blockHash` - hash of the block as `int256`.\n\nReturns `int256`\n* address of the recipient\n\n----\n\n##### getFeeAmount(blockHash)\n\nGet the fee amount in wei for verifications using a given `blockHash`.\n\n* `blockHash` - hash of the block as `int256`.\n\nReturns `int256`\n* amount of the fee in wei.\n\n----\n\n##### getChangeRecipientFee()\n\nGet the amount of wei required that must be sent to BTC Relay when calling\n`changeFeeRecipient`.\n\nReturns `int256`\n* amount of wei\n\n----\n\n## Development\n\nRequirements\n* [Serpent](https://github.com/ethereum/serpent)\n* [pyethereum](https://github.com/ethereum/pyethereum) (for tests)\n* [pyepm](https://github.com/etherex/pyepm) (for deployment)\n\n#### Running tests\n\nExclude slow tests:\n```\npy.test test/ -s -m \"not slow\"\n```\n\nRun slow tests without veryslow tests\n```\npy.test test/ -s -m \"slow and not veryslow\"\n```\n\nAll tests:\n```\npy.test test/ -s\n```\n\n\n## License\n\nSee [full MIT License](LICENSE) including:\n```\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethereum%2Fbtcrelay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fethereum%2Fbtcrelay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethereum%2Fbtcrelay/lists"}