ADD more text

pull/1/head
pubkey 7 years ago
parent fd67304da5
commit 5bcc264d10
  1. 76
      contracts/DonationBag.sol
  2. 108
      tutorials/signed-data.md

@ -0,0 +1,76 @@
pragma solidity 0.4.20;
contract DonationBag {
// dontaion-signatures must be created by the owner
address public owner;
// each donation contains this amount of wei
uint public amountPerDonation = 1000 * 1000;
// one address can recieve only one donation
// the ones already recieved one, are stored here
mapping (address => bool) public alreadyRecieved;
// constructor
function DonationBag(address _owner) public {
owner = _owner;
}
/**
* to ensure the signatures for this contract cannot be
* replayed somewhere else, we add this prefix to the signed hash
*/
string public signPrefix = "Signed for DonationBag:";
/**
* validates if the signature is valid
* by checking if the correct message was signed
* which consists of <signPrefix><contractAddress><receiverAddress>
*/
function isSignatureValid(
address receiver,
uint8 v,
bytes32 r,
bytes32 s
) public constant returns (bool correct) {
bytes32 mustBeSigned = keccak256(
signPrefix,
this,
receiver
);
address signer = ecrecover(
mustBeSigned,
v, r, s
);
return (signer == owner && receiver == msg.sender);
}
/**
* checks if the signature and message is valid
* if yes we send some wei to the submitter
*/
function recieveDonation(
address receiver,
uint8 v,
bytes32 r,
bytes32 s
) public {
// already recieved donation -> revert
if (alreadyRecieved[msg.sender] == true) revert();
// signature not valid -> revert
if (isSignatureValid(
receiver,
v, r, s
) == false) {
revert();
}
// all valid -> send wei
msg.sender.transfer(amountPerDonation);
}
}

@ -1,84 +1,80 @@
# Sign and validate data with solidity
In this tutorial we will sign data with javascript and later validate the signatur at a solidity smart-contract.
In this tutorial we will sign data with javascript and later validate the signatur in a solidity smart-contract.
## sign the data
First we create an identity and sign a message with it.
## prerequisites
First we create two identities, `creator` and `receiver`.
```javascript
const EthCrypto = require('eth-crypto');
const creatorIdentity = EthCrypto.createIdentity();
const recieverIdentity = EthCrypto.createIdentity();
const message = 'Give me the money:' + recieverIdentity.address;
```
const signature = EthCrypto.sign(
identity.privateKey,
message
);
Then we start a local testnet to use later. At the testnet, we givbe the creatorIdentity a balance of 10 ether.
console.dir(signature);
/* > {
v: '0x1b',
r: '0xc04b809d8f33c46ff80c44ba58e866...',
s: '0x757a3393b695ba83b2aba0c35c1503...'
}
*/
```javascript
const Web3 = require('web3');
const ganache = require('ganache-cli');
// create a web3-instance
const web3 = new Web3();
// create a ganache-provider
const ganacheProvider = ganache.provider({
// we preset the balance of our identity to 10 ether
accounts: {
// we have to remove the trailing '0x' so ganache accepts our key
secretKey: creatorIdentity.privateKey.replace(/^.{2}/g, ''),
balance: web3.utils.toWei('10', 'ether')
}
});
// set ganache to web3 as provider
web3.setProvider(ganacheProvider);
```
## create a smart-contract that validate the signature
## create a smart-contract that can validate signatures
Lets create an example-contract. The contract will be a donation-bag which contains some ether and has an owner.
Whenever someone submits a valid donation-signature, he recieves a part of the contracts value.
Whenever someone submits a valid donation-signature, he recieves a part of the contracts value. This allows the creator of the contract to give signed data to people **off-chain** which they can later use to claim the value **on-chain**.
Write this in a file called `DonationBag.sol`.
Write the contracts code in a file called `DonationBag.sol`. See the content [here](../contracts/DonationBag.sol).
```javascript
pragma solidity 0.4.20;
As you can see, the contract has some methods:
contract DonationBag {
- DonationBag(): The constructor which is called when the contract is created. Here we set the owner of the DonationBag
- isSignatureValid(): checks if a given signature is really signed by the sender and contains the correct content.
- recieveDonation(): This is called by the receiver when the donation is claimed.
// dontaion-signatures must be created by the owner
address owner;
## deploy the contract
// each donation contains this amount of wei
uint amountPerDonation = 1000 * 1000;
Before we can put the contract on our local blockchain. We have to compile the solidity-code to bytecode.
// one address can recieve only one donation
// the ones already recieved one, are stored here
mapping (address => bool) alreadyRecieved;
// constructor
function DonationBag(address _owner) public {
owner = _owner;
}
/**
* checks if the signature and message is valid
* if yes we send some wei to the submitter
*/
function recieveDonation(
bytes32 message,
uint8 v,
bytes32 r,
bytes32 s
) public {
```javascript
const solc = require('solc');
const fs = require('fs');
const path = require('path');
const contractPath = path.join(__dirname, '../contracts/DonationBag.sol');
// already recieved donation -> revert
if(alreadyRecieved[msg.sender] == true) revert();
// read solidity-code from file
const contractCode = fs.readFileSync(contractPath, 'utf8');
address signer = ecrecover(
message,
v, r, s
);
// compile the code into an object
const compiled = solc.compile(contractCode, 1).contracts[':DonationBag'];
// signature not valid -> revert
if(signer != owner) revert();
console.dir(compiled);
/* > {
interface: [...],
bytecode: '10390f35b34156101ef57600...'
}
*/
```
Now that we have the bytecode of the contract, we can submit a transaction to create a new instance of it at our local blockchain.
// all valid -> send wei
msg.sender.transfer(amountPerDonation);
}
}
```javascript
```

Loading…
Cancel
Save