Skip to content

Instantly share code, notes, and snippets.

@AlexShkor
Created January 3, 2018 14:07
Show Gist options
  • Save AlexShkor/42bf4d6c40741fa3b2dae96b9aa6b1bb to your computer and use it in GitHub Desktop.
Save AlexShkor/42bf4d6c40741fa3b2dae96b9aa6b1bb to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.17;
contract AtomicSwap {
enum State { Empty, Initiator, Participant }
struct Swap {
uint initTimestamp;
uint refundTime;
bytes20 hashedSecret;
bytes32 secret;
address initiator;
address participant;
uint256 value;
bool emptied;
State state;
}
mapping(bytes20 => Swap) public swaps;
event Refunded(uint _refundTime);
event Redeemed(uint _redeemTime);
function AtomicSwap() {}
modifier isRefundable(bytes20 _hashedSecret) {
require(block.timestamp > swaps[_hashedSecret].initTimestamp + swaps[_hashedSecret].refundTime);
require(swaps[_hashedSecret].emptied == false);
_;
}
modifier isRedeemable(bytes20 _hashedSecret, bytes32 _secret) {
require(ripemd160(_secret) == _hashedSecret);
require(block.timestamp < swaps[_hashedSecret].initTimestamp + swaps[_hashedSecret].refundTime);
require(swaps[_hashedSecret].emptied == false);
_;
}
function getHash(bytes32 secret) constant returns(bytes20){
return ripemd160(secret);
}
function doesMatch(bytes20 _hashedSecret, bytes32 _secret) constant returns (bool){
return ripemd160(_secret) == _hashedSecret;
}
modifier isInitiator(bytes20 _hashedSecret) {
require(msg.sender == swaps[_hashedSecret].initiator);
_;
}
modifier isNotInitiated(bytes20 _hashedSecret) {
require(swaps[_hashedSecret].state == State.Empty);
_;
}
function initiate (bytes20 _hashedSecret,address _participant)
payable
isNotInitiated(_hashedSecret)
{
swaps[_hashedSecret].refundTime = 48 hours;
swaps[_hashedSecret].initTimestamp = block.timestamp;
swaps[_hashedSecret].hashedSecret = _hashedSecret;
swaps[_hashedSecret].participant = _participant;
swaps[_hashedSecret].initiator = msg.sender;
swaps[_hashedSecret].state = State.Initiator;
swaps[_hashedSecret].value = msg.value;
}
function participate(bytes20 _hashedSecret,address _initiator)
payable
isNotInitiated(_hashedSecret)
{
swaps[_hashedSecret].refundTime = 24 hours;
swaps[_hashedSecret].initTimestamp = block.timestamp;
swaps[_hashedSecret].participant = msg.sender;
swaps[_hashedSecret].initiator = _initiator;
swaps[_hashedSecret].value = msg.value;
swaps[_hashedSecret].hashedSecret = _hashedSecret;
swaps[_hashedSecret].state = State.Participant;
}
function redeem(bytes32 _secret, bytes20 _hashedSecret)
isRedeemable(_hashedSecret, _secret)
{
if(swaps[_hashedSecret].state == State.Participant){
swaps[_hashedSecret].initiator.transfer(swaps[_hashedSecret].value);
}
if(swaps[_hashedSecret].state == State.Initiator){
swaps[_hashedSecret].participant.transfer(swaps[_hashedSecret].value);
}
swaps[_hashedSecret].emptied = true;
Redeemed(block.timestamp);
swaps[_hashedSecret].secret = _secret;
}
function refund(bytes20 _hashedSecret)
isRefundable(_hashedSecret)
{
if(swaps[_hashedSecret].state == State.Participant){
swaps[_hashedSecret].participant.transfer(swaps[_hashedSecret].value);
}
if(swaps[_hashedSecret].state == State.Initiator){
swaps[_hashedSecret].initiator.transfer(swaps[_hashedSecret].value);
}
swaps[_hashedSecret].emptied = true;
Refunded(block.timestamp);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment