Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/chatch/hashed-timelock-contract-ethereum
Hashed Timelock Contracts for ETH, ERC20 and ERC721 on Ethereum
https://github.com/chatch/hashed-timelock-contract-ethereum
atomic-swap blockchain cryptocurrencies erc20 erc721 ethereum hashlock htlc smart-contracts solidity timelock
Last synced: 3 days ago
JSON representation
Hashed Timelock Contracts for ETH, ERC20 and ERC721 on Ethereum
- Host: GitHub
- URL: https://github.com/chatch/hashed-timelock-contract-ethereum
- Owner: chatch
- License: gpl-3.0
- Created: 2017-09-15T02:54:50.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2021-07-26T05:43:08.000Z (over 3 years ago)
- Last Synced: 2024-12-16T09:07:44.423Z (10 days ago)
- Topics: atomic-swap, blockchain, cryptocurrencies, erc20, erc721, ethereum, hashlock, htlc, smart-contracts, solidity, timelock
- Language: JavaScript
- Homepage:
- Size: 960 KB
- Stars: 223
- Watchers: 16
- Forks: 110
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# hashed-timelock-contract-ethereum
[![NPM Package](https://img.shields.io/npm/v/ethereum-htlc.svg?style=flat-square)](https://www.npmjs.org/package/ethereum-htlc)
[![Build Status](https://travis-ci.com/chatch/hashed-timelock-contract-ethereum.svg?branch=master)](https://travis-ci.com/chatch/hashed-timelock-contract-ethereum)[Hashed Timelock Contracts](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) (HTLCs) for Ethereum:
- [HashedTimelock.sol](contracts/HashedTimelock.sol) - HTLC for native ETH token
- [HashedTimelockERC20.sol](contracts/HashedTimelockERC20.sol) - HTLC for ERC20 tokens
- [HashedTimelockERC721.sol](contracts/HashedTimelockERC721.sol) - HTLC for ERC721 tokensUse these contracts for creating HTLCs on the Ethereum side of a cross chain atomic swap (for example the [xcat](https://github.com/chatch/xcat) project).
## Run Tests
* Install dependencies
* Start [Ganache](https://www.trufflesuite.com/ganache) with network ID `4447`
* Run the [Truffle](https://www.trufflesuite.com/truffle) tests```
$ npm install
$ npm run ganache-start
$ npm run test
Using network 'test'.Compiling ./test/helper/ASEANToken.sol...
Compiling ./test/helper/EUToken.sol...Contract: HashedTimelock
✓ newContract() should create new contract and store correct details (92ms)
✓ newContract() should fail when no ETH sent (84ms)
✓ newContract() should fail with timelocks in the past (78ms)
✓ newContract() should reject a duplicate contract request (159ms)
✓ withdraw() should send receiver funds when given the correct secret preimage (214ms)
✓ withdraw() should fail if preimage does not hash to hashX (111ms)
✓ withdraw() should fail if caller is not the receiver (162ms)
✓ withdraw() should fail after timelock expiry (1243ms)
✓ refund() should pass after timelock expiry (1273ms)
✓ refund() should fail before the timelock expiry (132ms)
✓ getContract() returns empty record when contract doesn't exist (48ms)Contract: HashedTimelockERC20
✓ newContract() should create new contract and store correct details (214ms)
✓ newContract() should fail when no token transfer approved (107ms)
✓ newContract() should fail when token amount is 0 (166ms)
✓ newContract() should fail when tokens approved for some random account (214ms)
✓ newContract() should fail when the timelock is in the past (136ms)
✓ newContract() should reject a duplicate contract request (282ms)
✓ withdraw() should send receiver funds when given the correct secret preimage (363ms)
✓ withdraw() should fail if preimage does not hash to hashX (227ms)
✓ withdraw() should fail if caller is not the receiver (307ms)
✓ withdraw() should fail after timelock expiry (2257ms)
✓ refund() should pass after timelock expiry (2407ms)
✓ refund() should fail before the timelock expiry (283ms)
✓ getContract() returns empty record when contract doesn't exist (55ms)Contract: HashedTimelock swap between two ERC20 tokens
✓ Step 1: Alice sets up a swap with Bob in the AliceERC20 contract (233ms)
✓ Step 2: Bob sets up a swap with Alice in the BobERC20 contract (239ms)
✓ Step 3: Alice as the initiator withdraws from the BobERC20 with the secret (97ms)
✓ Step 4: Bob as the counterparty withdraws from the AliceERC20 with the secret learned from Alice's withdrawal (144ms)
Test the refund scenario:
✓ the swap is set up with 5sec timeout on both sides (3613ms)Contract: HashedTimelock swap between ERC721 token and ERC20 token (Delivery vs. Payment)
✓ Step 1: Alice sets up a swap with Bob to transfer the Commodity token #1 (256ms)
✓ Step 2: Bob sets up a swap with Alice in the payment contract (231ms)
✓ Step 3: Alice as the initiator withdraws from the BobERC721 with the secret (95ms)
✓ Step 4: Bob as the counterparty withdraws from the AliceERC721 with the secret learned from Alice's withdrawal (132ms)
Test the refund scenario:
✓ the swap is set up with 5sec timeout on both sides (3737ms)Contract: HashedTimelock swap between two ERC721 tokens
✓ Step 1: Alice sets up a swap with Bob in the AliceERC721 contract (225ms)
✓ Step 2: Bob sets up a swap with Alice in the BobERC721 contract (265ms)
✓ Step 3: Alice as the initiator withdraws from the BobERC721 with the secret (131ms)
✓ Step 4: Bob as the counterparty withdraws from the AliceERC721 with the secret learned from Alice's withdrawal (119ms)
Test the refund scenario:
✓ the swap is set up with 5sec timeout on both sides (3635ms)39 passing (27s)
```## Protocol - Native ETH
### Main flow
![](docs/sequence-diagram-htlc-eth-success.png?raw=true)
### Timelock expires
![](docs/sequence-diagram-htlc-eth-refund.png?raw=true)
## Protocol - ERC20
### Main flow
![](docs/sequence-diagram-htlc-erc20-success.png?raw=true)
### Timelock expires
![](docs/sequence-diagram-htlc-erc20-refund.png?raw=true)
## Interface
### HashedTimelock
1. `newContract(receiverAddress, hashlock, timelock)` create new HTLC with given receiver, hashlock and expiry; returns contractId bytes32
2. `withdraw(contractId, preimage)` claim funds revealing the preimage
3. `refund(contractId)` if withdraw was not called the contract creator can get a refund by calling this some time after the time lock has expired.See [test/htlc.js](test/htlc.js) for examples of interacting with the contract from javascript.
### HashedTimelockERC20
1. `newContract(receiverAddress, hashlock, timelock, tokenContract, amount)` create new HTLC with given receiver, hashlock, expiry, ERC20 token contract address and amount of tokens
2. `withdraw(contractId, preimage)` claim funds revealing the preimage
3. `refund(contractId)` if withdraw was not called the contract creator can get a refund by calling this some time after the time lock has expired.See [test/htlcERC20.js](test/htlcERC20.js) for examples of interacting with the contract from javascript.
### HashedTimelockERC721
1. `newContract(receiverAddress, hashlock, timelock, tokenContract, tokenId)` create new HTLC with given receiver, hashlock, expiry, ERC20 token contract address and the token to transfer
2. `withdraw(contractId, preimage)` claim funds revealing the preimage
3. `refund(contractId)` if withdraw was not called the contract creator can get a refund by calling this some time after the time lock has expired.