Skip to content

Latest commit

 

History

History
227 lines (181 loc) · 6.83 KB

bitcoin_ethereum_simple_contract.org

File metadata and controls

227 lines (181 loc) · 6.83 KB

简单合约示例

set,get()方法示例

这是一个简单的set(),get()一个值的合约,并且还包括了一个发行代币的示例。

也有一些log的功能。

contract Token {
    address issuer;
    uint public tk;
    mapping (address => uint) balances;
    event Issue(address account, uint amount);
    event Transfer(address from, address to, uint amount);
    function Token() {
        issuer = msg.sender;
    }      
    function issue(address account, uint amount) {
        if (msg.sender != issuer) throw;
        balances[account] += amount;
    }      
    function transfer(address to, uint amount) {
        if (balances[msg.sender] < amount) throw;
        balances[msg.sender] -= amount;
        balances[to] += amount;
        Transfer(msg.sender, to, amount);
    }      
    function getBalance(address account) constant returns (uint) {
        return balances[account];
    } 
    function set_tk(uint a) public {
        tk += a;
    }
    function get_tk() public constant returns (uint) {
        return tk;
    }
}

OneThousand

OneThousand

contract TheLuckyOne {
    address owner;
    mapping(uint => address) public tickets; //All tickets, ever, in order
    mapping(uint => uint) public winners; //All winners, ever, in order
    
    uint public numTickets; //Number of tickets bought lifetime
    uint public numWinners; //Number of pots awarded lifetime
    uint public lastProcessed; //Last index of tickets processed
    uint public lastBlock; //Last block of the round to be processed
    
    bytes32 public clientSeed; //Client seed
    bytes32 public curSecretHash; //Hash of server seed
    bytes32 public lastBlockHash; //Block hash to use
    bytes32 public lastClientSeed; //Client seed to use
    
    uint public constant TICKETSPERROUND = 1000; //Number of tickets per round
    uint public constant TIMEOUT = 24 hours;
    uint public constant ETHERVAL = 1000000000000000000;
    
    uint public deadlineStart; //Value of 0 means no deadline
    
    event Log(uint value);
    
    function TheLuckyOne(bytes32 initialSecretHash) {
        
        curSecretHash = initialSecretHash;
        owner = msg.sender;
        
    }
    
    //Withdraw excess funds, keeping enough for payouts
    function adminWithdraw() {
        if (msg.sender != owner) {
            return;
        }
        
        //Can't withdraw the amount needed for payout
        uint frozenValue = ((numTickets - lastProcessed) * ETHERVAL);
        
        //Withdraw the rest
        Log(this.balance - frozenValue);
        msg.sender.send(this.balance - frozenValue);
    }
    
    //Get time in seconds since deadline, returns 1337 if no deadline
    function getTimeElapsed() constant returns(uint) {
        if (deadlineStart == 0) {
            return 1337;
        } else {
            return block.timestamp - deadlineStart;
        }
    }
    
    //Clone of sha3
    function sha3clone(bytes32 input) constant returns (bytes32) {
        return sha3(input);
    }
    
    //Return funds to players if server seed not released in time
    function recoverLostFunds() {
        //No deadline
        if (deadlineStart == 0) {
            return;
        }
        //Deadline not hit yet
        if (block.timestamp - deadlineStart < TIMEOUT) {
            return;
        }
        
        //Destroy the hash to prevent supplying a working seed at this phase
        curSecretHash = 0;

        uint toSend = 0;
        //Calculate how much to pay based off tickets
        for (var i = lastProcessed; i < numTickets; i++) {
            if (tickets[i] == msg.sender) {
                toSend += ETHERVAL;
            }
        }
        
        //Refund full ticket value
        msg.sender.send(toSend);
    }
    
    //Reveal seed and pay out last round
    function revealAndPayout(bytes32 curSecret, bytes32 nextSecretHash) {
        
        //Not admin
        if (msg.sender != owner) {
            return;
        }
        
        //Invalid Seed
        if (sha3(curSecret) != curSecretHash || curSecretHash == 0) {
            return; 
        }
        
        //Payout premature
        if (numTickets < TICKETSPERROUND || 
            lastProcessed > numTickets - TICKETSPERROUND) {
            return;
        }
        
        //Fetch the non-server sources of entropy
        bytes32 serverClientHash = sha3(curSecret, lastClientSeed);
        
        //Calculate winner and pay out
        uint winnerIdx = 
            lastProcessed + uint(serverClientHash ^ lastBlockHash) % TICKETSPERROUND;
        tickets[winnerIdx].send(TICKETSPERROUND * ETHERVAL); 
        Log (winnerIdx);
        
        //Record win
        winners[numWinners++] = winnerIdx;
        
        //Update state variables for next pot
        lastProcessed += TICKETSPERROUND;
        
        //Reset deadline
        deadlineStart = 0;
        
        //Update seed
        curSecretHash = nextSecretHash;
        
    }
    
    function () {
        
        uint ticketsBought;
        
        //Calculate tickets bought
        //Price is 1.025 ETH per ticket for 25+ tickets
        if (msg.value >= 25625 finney) {
            ticketsBought = msg.value/1025000000000000000;
            //Refund difference
            msg.sender.send(msg.value % 1025000000000000000);
        }
        //Price is 1.050 ETH per ticket for 10+ tickets
        else if (msg.value >= 10500 finney) {
            ticketsBought = msg.value/1050000000000000000;
            //Refund difference
            msg.sender.send(msg.value % 1050000000000000000);
        }
        //Price is 1.100 ETH per ticket for 5+ tickets
        else if (msg.value >= 5500 finney) {
            ticketsBought = msg.value/1100000000000000000;
            //Refund difference
            msg.sender.send(msg.value % 1100000000000000000);
        }
        //Price is 1.150 ETH per ticket for 1+ tickets
        else {
            ticketsBought = msg.value/1150000000000000000;
            //Refund difference
            msg.sender.send(msg.value % 1150000000000000000);
        }
        
        //Update client seed
        clientSeed = sha3(clientSeed, msg.sender, msg.value);
        
        //If this is the final ticket, record the block and set the deadline
        if (numTickets/TICKETSPERROUND != (numTickets + ticketsBought)/TICKETSPERROUND) {
            lastBlock = block.number;
            lastClientSeed = clientSeed;
            deadlineStart = block.timestamp;
        }
        
        //Update blockhash (done here because of 256 timeout)
        if (block.blockhash(lastBlock + 1) != 0) {
            lastBlockHash = block.blockhash(lastBlock + 1);
        }
        
        //Buys a ticket for each ether
        for (var i = 1; i <= ticketsBought; i += 1) {
            tickets[numTickets++] = msg.sender;
        }
    }
}