Many minor updates

This commit is contained in:
Nemil Dalal 2015-11-30 15:45:03 -05:00
parent 1f4738cbc7
commit 700f3e7a1c

View File

@ -14,7 +14,7 @@ As Solidity and Ethereum are under active development, experimental or beta feat
```javascript ```javascript
// Let's start with a simple Bank contract, before diving into to the key components of the language // Let's start with a simple Bank contract, before diving into to the key components of the language
// START EXAMPLE // ** START EXAMPLE **
// Start with a Natspec comment (the three slashes) that can be used // Start with a Natspec comment (the three slashes) that can be used
// for documentation - and as descriptive data for UI elements // for documentation - and as descriptive data for UI elements
/// @title A simple deposit/withdrawal bank built on Bitcoin /// @title A simple deposit/withdrawal bank built on Bitcoin
@ -29,8 +29,7 @@ contract AcmeBank {
mapping (address => uint) balances; mapping (address => uint) balances;
// the 'public' makes 'owner' externally readable by users or contracts // the 'public' makes 'owner' externally readable by users or contracts
// (but not writeable), the 'constant' means this value to be // (but not writeable) -
// changed after initialization
address public owner; address public owner;
// Constructor, can receive one or many variables here // Constructor, can receive one or many variables here
@ -40,13 +39,13 @@ contract AcmeBank {
owner = msg.sender; // msg.sender refers to the address of the contract creator owner = msg.sender; // msg.sender refers to the address of the contract creator
} }
function deposit(uint balance) { function deposit(uint balance) public {
balances[msg.sender] += msg.value; // no need for "this." or "self." in front of the state variable balances[msg.sender] += msg.value; // no need for "this." or "self." in front of the state variable
return balances[msg.sender]; // msg.sender refers to the contract caller return balances[msg.sender]; // msg.sender refers to the contract caller
} }
function withdraw(uint withdrawAmount) returns (uint remainingBalance) { function withdraw(uint withdrawAmount) public returns (uint remainingBalance) {
if(balances[msg.sender] >= withdrawAmount) { if(balances[msg.sender] >= withdrawAmount) {
balances[msg.sender] -= withdrawAmount; balances[msg.sender] -= withdrawAmount;
@ -58,8 +57,9 @@ contract AcmeBank {
} }
} }
// It's good practice to have a remove function, which disables this contract - but does mean that users have to trust the owner // It's good practice to have a remove function, which disables this
function remove () { // contract - but does mean that users have to trust the owner
function remove() {
if(msg.sender == owner) { // Only let the contract creator do this if(msg.sender == owner) { // Only let the contract creator do this
suicide(owner); // suicide makes this contract inactive, and returns funds to the owner suicide(owner); // suicide makes this contract inactive, and returns funds to the owner
} }
@ -71,29 +71,35 @@ contract AcmeBank {
} }
// Fallback function // Fallback function
// This function is called if invalid data is sent or ether without data; // The fallback function is called if none of the other functions matches the given function identifier.
// It is often meant to be called when invalid data is sent or ether without data.
// Added so that ether sent to this contract is reverted if the contract fails // Added so that ether sent to this contract is reverted if the contract fails
// otherwise, the sender loses their money; you should add this in most contracts // otherwise, the sender loses their money; you should add this in most contracts
function () { throw; } function () { throw; }
} }
// END EXAMPLE // ** END EXAMPLE **
// Now let's go through the basics of Solidity // Now let's go through the basics of Solidity
// 1. DATA TYPES // 1. DATA TYPES AND ASSOCIATED METHOD
// uint is the data type typically used for currency (there are no doubles // uint is the data type typically used for currency (there are no doubles
// or floats) and for dates // or floats) and for dates
uint x; uint x;
int constant a = 8; // int of 256 bits, cannot be changed after instantiation
// with 'constant', the compiler replaces each occurence with the acutal value
// int of 256 bits, cannot be changed after instantiation
int constant a = 8;
int256 constant a = 8; // same effect as line above, here the 256 is explict
// For both int and uint, you can explicitly set space in steps of 8
// e.g., int8, int16
uint8 b; uint8 b;
int64 c; int64 c;
// int256 is same as int
// For both int and uint, you can explicitly set space in steps of 8,
// e.g., int8, int16
uint248 e; uint248 e;
// Type casting // Type casting
int x = int(b) int x = int(b);
bool b = true; // or do 'var b = true;' for inferred typing bool b = true; // or do 'var b = true;' for inferred typing
@ -123,13 +129,14 @@ var a = true;
// by default, all values are set to 0 on instantiation // by default, all values are set to 0 on instantiation
// Delete can be called on most types, and will set the values to 0 // Delete can be called on most types, and will set the values to 0 by assignment
uint x = 5; uint x = 5;
delete(x); // x is now 0 delete(x); // x is now 0
// 2. DATA STRUCTURES // 2. DATA STRUCTURES
// Arrays // Arrays
bytes32[] names; bytes32[5] nicknames; // static array
bytes32[] names; // dynamic array
uint newLength = names.push("John"); // adding returns new length of the array uint newLength = names.push("John"); // adding returns new length of the array
// Length // Length
names.length; // get length names.length; // get length
@ -168,29 +175,39 @@ delete(b); // set all values to 0, except any mappings
enum State { Created, Locked, Inactive }; enum State { Created, Locked, Inactive };
State public state; // Declare variable from enum State public state; // Declare variable from enum
state = State.Created; state = State.Created;
// enums can be explicitly converted to ints
// Data locations: Memory vs. storage - all complex types (arrays, structs) have a data location
// 'memory' does not persist, 'storage' does
// Default is 'storage' for local and state variables; 'memory' for function parameters
// 3. Variables of note // 3. Variables of note
// storage - A persistent storage hash (does not need to be declared) // ** this **
storage['abc'] = 'def'; // maps 256 bit words to 256 bit words this; // the address of the current contract
// 'balance' often used at the end of a contracts life to send the
// remaining balance to a party
this.balance;
this.someFunction(); // calls a function externally (via a message call, not via an internal jump)
// tx - This transaction // ** msg - The current message received by the contract ** **
tx.origin // address, sender of the transaction
tx.gasprice // uint, gas price of the transaction
// msg - The current message received by the contract
msg.sender; // address, The address of the sender msg.sender; // address, The address of the sender
msg.value; // uint, The amount of gas provided to this contract in wei msg.value; // uint, The amount of gas provided to this contract in wei
msg.data // bytes, complete call data msg.data; // bytes, complete call data
msg.gas; // remaining gas
// balance of the current contract (both contract and external accounts // ** tx - This transaction **
// have balances) - often used at the end of a contracts life to send the tx.origin; // address, sender of the transaction
// remaining balance to a party tx.gasprice; // uint, gas price of the transaction
this.balance
// block // ** block - Information about the current block **
now // uint, current time, alias for block.timestamp now // uint, current time, alias for block.timestamp
block.number // uint, current block number block.number; // uint, current block number
block.difficulty // uint, current block difficulty block.difficulty; // uint, current block difficulty
block.blockhash(1) // returns bytes32, only provides for most recent 256 block block.blockhash(1); // returns bytes32, only provides for most recent 256 blocks
block.gasLimit();
// ** storage - A persistent storage hash (does not need to be declared) **
storage['abc'] = 'def'; // maps 256 bit words to 256 bit words
// 4. FUNCTIONS AND MORE // 4. FUNCTIONS AND MORE
// A. Functions // A. Functions
@ -236,7 +253,7 @@ function b() {
// B. Events // B. Events
// Events are an easy way to notify external listeners that something changed // Events are an easy way to notify external listeners that something changed
// You typically decalre them after your contract parameters // You typically declare them after your contract parameters
event Sent(address from, address to, uint amount); event Sent(address from, address to, uint amount);
// You then call it in a function, when you want to trigger it // You then call it in a function, when you want to trigger it
@ -259,37 +276,49 @@ Coin.Sent().watch({}, '', function(error, result) {
// contract) // contract)
// C. Modifiers // C. Modifiers
// Modifiers let you validate inputs to functions // Modifiers let you validate inputs to functions such as a minimal balance or user authentication
// The '_' (underscore) must be included, and is an indicator that the // It's similar to a guard clause in other languages
// The '_' (underscore) must be included as the last line in the function body, and is an indicator that the
// function being called should be placed there // function being called should be placed there
modifier onlyBefore(uint _time) { if (now >= _time) throw; _ } modifier onlyBefore(uint _time) { if (now >= _time) throw; _ }
// You can then append it right after the function declaration // You can then append it right after the function declaration
function test() function changeOwner(newOwner)
onlyBefore() onlyBefore(someTime)
{ {
owner = newOwner;
} }
// 5. BRANCHING AND LOOPS // 5. BRANCHING AND LOOPS
// All basic logic blocks work - including if/else, for, while, break, continue, return // All basic logic blocks work - including if/else, for, while, break, continue, return
// switch is not provided // switch is not provided
// Syntax is the same as javascript, but there is no type conversion from // Syntax is the same as javascript, but there is no type conversion from
// non-boolean to boolean // non-boolean to boolean, so comparison operators must be used to get the boolean value
// 6. CALLING AN EXTERNAL CONTRACT // 6. OBJECTS/CONTRACTS
// A. Calling an external contract
contract infoFeed { contract infoFeed {
function info() returns (uint ret) { return 42; } function info() returns (uint ret) { return 42; }
} }
contract Consumer { contract Consumer {
InfoFeed feed; // create a variable that will point to a contract on the blockchain InfoFeed feed; // create a variable that will point to a contract on the blockchain
// Set feed to an existing contract
function setFeed(address addr) { function setFeed(address addr) {
// Link to the contract by creating on the address // Link to the contract by creating on the address
feed = InfoFeed(addr); feed = InfoFeed(addr);
} }
// Set feed based to a new instance of the contract
function createNewFeed() {
feed = new InfoFeed();
}
function callFeed() { function callFeed() {
// T final parentheses call the contract, optionally adding // T final parentheses call the contract, optionally adding
// custom value or gas numbers // custom value or gas numbers
@ -297,6 +326,30 @@ contract Consumer {
} }
} }
// B. Inheritance
// Order matters, last inherited contract (i.e., 'def') can override parts of the previously
// inherited contracts
contact MyContract is abc, def("a custom argument to def") {
// Override function
function z() {
if (msg.sender == owner) {
def.z(); // call overridden function
}
}
};
// C. Import
import "filename";
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
// Importing is under active development and will change
// Importing cannot currently be done at the command line
// 7. CONTRACT DESIGN PATTERNS // 7. CONTRACT DESIGN PATTERNS
// A. Obfuscation // A. Obfuscation
@ -317,6 +370,13 @@ if (!addr.send(123)) {
// Suicide // Suicide
suicide(SOME_ADDRESS); // suicide the current contract, sending funds to the address (often the creator) suicide(SOME_ADDRESS); // suicide the current contract, sending funds to the address (often the creator)
// This is a common pattern that lets the owner end the contract
function remove() {
if(msg.sender == owner) { // Only let the contract creator do this
suicide(owner); // suicide makes this contract inactive, and returns funds to the owner
}
}
// D. Storage optimization // D. Storage optimization
// Reading and writing can be expensive, as data needs to be stored in the // Reading and writing can be expensive, as data needs to be stored in the
// blockchain forever - this encourages smart ways to use memory (eventually, // blockchain forever - this encourages smart ways to use memory (eventually,
@ -324,19 +384,20 @@ suicide(SOME_ADDRESS); // suicide the current contract, sending funds to the add
// planning your data structures) // planning your data structures)
// *** EXAMPLE: Let's do a more complex example *** // *** EXAMPLE: Let's do a more complex example ***
// ** START EXAMPLE **
// [TODO: Decide what a more complex example looks like, needs a few characteristics: // [TODO: Decide what a more complex example looks like, needs a few characteristics:
// - has a 'constant' state variable // - has a 'constant' state variable
// - has a state machine (uses modifier) // - has a state machine (and uses modifier)
// - sends money to an address // - sends money to an address
// - gets information from another contract (we'll show code for both contracts) // - gets information from another contract (we'll show code for both contracts)
// - Shows inheritance // - Shows inheritance
// - show variables being passed in on instantiation (and guard code to throw if variables not provided) // - show variables being passed in on instantiation (and guard code to throw if variables not provided)
// - Shows the swapping out of a contract // - Shows the swapping out of a contract address
// Ideas: // Ideas:
// - crowdfunding? // - crowdfunding?
// - Peer to peer insurance // - Peer to peer insurance
// ] // ]
// *** END EXAMPLE *** // *** END EXAMPLE ***
// Some final points // Some final points
@ -366,21 +427,21 @@ sha3("ab", "cd");
ripemd160("abc"); ripemd160("abc");
sha256("def"); sha256("def");
// These are natspec comments, when a user is asked to confirm a transaction // 8. COMMON MISTAKES/MISCONCEPTIONS
/// // A few common mistakes and misconceptions:
/** */
// 8. COMMON MISTAKES // A. You cannot restrict a human or computer from reading the content of
// A few common mistakes
// You cannot restrict a human or computer from reading the content of
// your transaction or a transaction's state // your transaction or a transaction's state
// All data to the start of time is stored in the blockchain, so you and // All data to the start of time is stored in the blockchain, so you and
// anyone can observe all previous data states // anyone can observe all previous data stats
// 9. TESTING // When you don't specify public on a variable, you are indicating that other *contracts* can't
// read the data - but any person can still read the data
// 10. STYLE NOTES // TODO
// 9. STYLE NOTES
// Use 4 spaces for indentation // Use 4 spaces for indentation
// (Python's PEP8 is used as the baseline style guide, including its general philosophy) // (Python's PEP8 is used as the baseline style guide, including its general philosophy)
``` ```
@ -391,4 +452,7 @@ sha256("def");
- [Browser-based Solidity Editor](http://chriseth.github.io/browser-solidity/) - [Browser-based Solidity Editor](http://chriseth.github.io/browser-solidity/)
- [Gitter Chat room](https://gitter.im/ethereum/go-ethereum) - [Gitter Chat room](https://gitter.im/ethereum/go-ethereum)
## Information purposefully excluded
- Libraries
Feel free to send a pull request with any edits - or email nemild -/at-/ gmail Feel free to send a pull request with any edits - or email nemild -/at-/ gmail