├── CHEAT.sol ├── ETHEREUM.md ├── LICENSE.md ├── NEWS.md └── README.md /CHEAT.sol: -------------------------------------------------------------------------------- 1 | // note: code copied from Learn X in Y Minutes (Where X=Solidity) 2 | // see https://learnxinyminutes.com/docs/solidity/ and 3 | // https://learnxinyminutes.com/docs/files/learnSolidity.sol 4 | 5 | 6 | 7 | 8 | // First, a simple Bank contract 9 | // Allows deposits, withdrawals, and balance checks 10 | 11 | // simple_bank.sol (note .sol extension) 12 | /* **** START EXAMPLE **** */ 13 | 14 | // Declare the source file compiler version 15 | pragma solidity ^0.6.6; 16 | 17 | // Start with Natspec comment (the three slashes) 18 | // used for documentation - and as descriptive data for UI elements/actions 19 | 20 | /// @title SimpleBank 21 | /// @author nemild 22 | 23 | /* 'contract' has similarities to 'class' in other languages (class variables, 24 | inheritance, etc.) */ 25 | contract SimpleBank { // CapWords 26 | // Declare state variables outside function, persist through life of contract 27 | 28 | // dictionary that maps addresses to balances 29 | // always be careful about overflow attacks with numbers 30 | mapping (address => uint) private balances; 31 | 32 | // "private" means that other contracts can't directly query balances 33 | // but data is still viewable to other parties on blockchain 34 | 35 | address public owner; 36 | // 'public' makes externally readable (not writeable) by users or contracts 37 | 38 | // Events - publicize actions to external listeners 39 | event LogDepositMade(address accountAddress, uint amount); 40 | 41 | // Constructor, can receive one or many variables here; only one allowed 42 | constructor() public { 43 | // msg provides details about the message that's sent to the contract 44 | // msg.sender is contract caller (address of contract creator) 45 | owner = msg.sender; 46 | } 47 | 48 | /// @notice Deposit ether into bank 49 | /// @return The balance of the user after the deposit is made 50 | function deposit() public payable returns (uint) { 51 | // Use 'require' to test user inputs, 'assert' for internal invariants 52 | // Here we are making sure that there isn't an overflow issue 53 | require((balances[msg.sender] + msg.value) >= balances[msg.sender]); 54 | 55 | balances[msg.sender] += msg.value; 56 | // no "this." or "self." required with state variable 57 | // all values set to data type's initial value by default 58 | 59 | emit LogDepositMade(msg.sender, msg.value); // fire event 60 | 61 | return balances[msg.sender]; 62 | } 63 | 64 | /// @notice Withdraw ether from bank 65 | /// @dev This does not return any excess ether sent to it 66 | /// @param withdrawAmount amount you want to withdraw 67 | /// @return remainingBal 68 | function withdraw(uint withdrawAmount) public returns (uint remainingBal) { 69 | require(withdrawAmount <= balances[msg.sender]); 70 | 71 | // Note the way we deduct the balance right away, before sending 72 | // Every .transfer/.send from this contract can call an external function 73 | // This may allow the caller to request an amount greater 74 | // than their balance using a recursive call 75 | // Aim to commit state before calling external functions, including .transfer/.send 76 | balances[msg.sender] -= withdrawAmount; 77 | 78 | // this automatically throws on a failure, which means the updated balance is reverted 79 | msg.sender.transfer(withdrawAmount); 80 | 81 | return balances[msg.sender]; 82 | } 83 | 84 | /// @notice Get balance 85 | /// @return The balance of the user 86 | // 'view' (ex: constant) prevents function from editing state variables; 87 | // allows function to run locally/off blockchain 88 | function balance() view public returns (uint) { 89 | return balances[msg.sender]; 90 | } 91 | } 92 | // ** END EXAMPLE ** 93 | 94 | 95 | // Now, the basics of Solidity 96 | 97 | // 1. DATA TYPES AND ASSOCIATED METHODS 98 | // uint used for currency amount (there are no doubles 99 | // or floats) and for dates (in unix time) 100 | uint x; 101 | 102 | // int of 256 bits, cannot be changed after instantiation 103 | int constant a = 8; 104 | int256 constant a = 8; // same effect as line above, here the 256 is explicit 105 | uint constant VERSION_ID = 0x123A1; // A hex constant 106 | // with 'constant', compiler replaces each occurrence with actual value 107 | 108 | // All state variables (those outside a function) 109 | // are by default 'internal' and accessible inside contract 110 | // and in all contracts that inherit ONLY 111 | // Need to explicitly set to 'public' to allow external contracts to access 112 | int256 public a = 8; 113 | 114 | // For int and uint, can explicitly set space in steps of 8 up to 256 115 | // e.g., int8, int16, int24 116 | uint8 b; 117 | int64 c; 118 | uint248 e; 119 | 120 | // Be careful that you don't overflow, and protect against attacks that do 121 | // For example, for an addition, you'd do: 122 | uint256 c = a + b; 123 | assert(c >= a); // assert tests for internal invariants; require is used for user inputs 124 | // For more examples of common arithmetic issues, see Zeppelin's SafeMath library 125 | // https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol 126 | 127 | 128 | // No random functions built in, you can get a pseduo-random number by hashing the current blockhash, or get a truly random number using something like Chainlink VRF. 129 | // https://docs.chain.link/docs/get-a-random-number 130 | 131 | // Type casting 132 | int x = int(b); 133 | 134 | bool b = true; // or do 'var b = true;' for inferred typing 135 | 136 | // Addresses - holds 20 byte/160 bit Ethereum addresses 137 | // No arithmetic allowed 138 | address public owner; 139 | 140 | // Types of accounts: 141 | // Contract account: address set on create (func of creator address, num transactions sent) 142 | // External Account: (person/external entity): address created from public key 143 | 144 | // Add 'public' field to indicate publicly/externally accessible 145 | // a getter is automatically created, but NOT a setter 146 | 147 | // All addresses can be sent ether 148 | owner.transfer(SOME_BALANCE); // fails and reverts on failure 149 | 150 | // Can also do a lower level .send call, which returns a false if it failed 151 | if (owner.send) {} // REMEMBER: wrap send in 'if', as contract addresses have 152 | // functions executed on send and these can fail 153 | // Also, make sure to deduct balances BEFORE attempting a send, as there is a risk of a recursive 154 | // call that can drain the contract 155 | 156 | // Can check balance 157 | owner.balance; // the balance of the owner (user or contract) 158 | 159 | 160 | // Bytes available from 1 to 32 161 | byte a; // byte is same as bytes1 162 | bytes2 b; 163 | bytes32 c; 164 | 165 | // Dynamically sized bytes 166 | bytes m; // A special array, same as byte[] array (but packed tightly) 167 | // More expensive than byte1-byte32, so use those when possible 168 | 169 | // same as bytes, but does not allow length or index access (for now) 170 | string n = "hello"; // stored in UTF8, note double quotes, not single 171 | // string utility functions to be added in future 172 | // prefer bytes32/bytes, as UTF8 uses more storage 173 | 174 | // Type inference 175 | // var does inferred typing based on first assignment, 176 | // can't be used in functions parameters 177 | var a = true; 178 | // use carefully, inference may provide wrong type 179 | // e.g., an int8, when a counter needs to be int16 180 | 181 | // var can be used to assign function to variable 182 | function a(uint x) returns (uint) { 183 | return x * 2; 184 | } 185 | var f = a; 186 | f(22); // call 187 | 188 | // by default, all values are set to 0 on instantiation 189 | 190 | // Delete can be called on most types 191 | // (does NOT destroy value, but sets value to 0, the initial value) 192 | delete x; 193 | 194 | 195 | // Destructuring/Tuples 196 | (x, y) = (2, 7); // assign/swap multiple values 197 | 198 | 199 | // 2. DATA STRUCTURES 200 | // Arrays 201 | bytes32[5] nicknames; // static array 202 | bytes32[] names; // dynamic array 203 | uint newLength = names.push("John"); // adding returns new length of the array 204 | // Length 205 | names.length; // get length 206 | names.length = 1; // lengths can be set (for dynamic arrays in storage only) 207 | 208 | // multidimensional array 209 | uint[][5] x; // arr with 5 dynamic array elements (opp order of most languages) 210 | 211 | // Dictionaries (any type to any other type) 212 | mapping (string => uint) public balances; 213 | balances["charles"] = 1; 214 | // balances["ada"] result is 0, all non-set key values return zeroes 215 | // 'public' allows following from another contract 216 | contractName.balances("charles"); // returns 1 217 | // 'public' created a getter (but not setter) like the following: 218 | function balances(string _account) returns (uint balance) { 219 | return balances[_account]; 220 | } 221 | 222 | // Nested mappings 223 | mapping (address => mapping (address => uint)) public custodians; 224 | 225 | // To delete 226 | delete balances["John"]; 227 | delete balances; // sets all elements to 0 228 | 229 | // Unlike other languages, CANNOT iterate through all elements in 230 | // mapping, without knowing source keys - can build data structure 231 | // on top to do this 232 | 233 | // Structs 234 | struct Bank { 235 | address owner; 236 | uint balance; 237 | } 238 | Bank b = Bank({ 239 | owner: msg.sender, 240 | balance: 5 241 | }); 242 | // or 243 | Bank c = Bank(msg.sender, 5); 244 | 245 | c.balance = 5; // set to new value 246 | delete b; 247 | // sets to initial value, set all variables in struct to 0, except mappings 248 | 249 | // Enums 250 | enum State { Created, Locked, Inactive }; // often used for state machine 251 | State public state; // Declare variable from enum 252 | state = State.Created; 253 | // enums can be explicitly converted to ints 254 | uint createdState = uint(State.Created); // 0 255 | 256 | // Data locations: Memory vs. storage vs. calldata - all complex types (arrays, 257 | // structs) have a data location 258 | // 'memory' does not persist, 'storage' does 259 | // Default is 'storage' for local and state variables; 'memory' for func params 260 | // stack holds small local variables 261 | 262 | // for most types, can explicitly set which data location to use 263 | 264 | 265 | // 3. Simple operators 266 | // Comparisons, bit operators and arithmetic operators are provided 267 | // exponentiation: ** 268 | // exclusive or: ^ 269 | // bitwise negation: ~ 270 | 271 | 272 | // 4. Global Variables of note 273 | // ** this ** 274 | this; // address of contract 275 | // often used at end of contract life to transfer remaining balance to party 276 | this.balance; 277 | this.someFunction(); // calls func externally via call, not via internal jump 278 | 279 | // ** msg - Current message received by the contract ** ** 280 | msg.sender; // address of sender 281 | msg.value; // amount of ether provided to this contract in wei, the function should be marked "payable" 282 | msg.data; // bytes, complete call data 283 | msg.gas; // remaining gas 284 | 285 | // ** tx - This transaction ** 286 | tx.origin; // address of sender of the transaction 287 | tx.gasprice; // gas price of the transaction 288 | 289 | // ** block - Information about current block ** 290 | now; // current time (approximately), alias for block.timestamp (uses Unix time) 291 | // Note that this can be manipulated by miners, so use carefully 292 | 293 | block.number; // current block number 294 | block.difficulty; // current block difficulty 295 | block.blockhash(1); // returns bytes32, only works for most recent 256 blocks 296 | block.gasLimit(); 297 | 298 | // ** storage - Persistent storage hash ** 299 | storage['abc'] = 'def'; // maps 256 bit words to 256 bit words 300 | 301 | 302 | // 5. FUNCTIONS AND MORE 303 | // A. Functions 304 | // Simple function 305 | function increment(uint x) returns (uint) { 306 | x += 1; 307 | return x; 308 | } 309 | 310 | // Functions can return many arguments, 311 | // and by specifying returned arguments name explicit return is not needed 312 | function increment(uint x, uint y) returns (uint x, uint y) { 313 | x += 1; 314 | y += 1; 315 | } 316 | // Call previous function 317 | uint (a,b) = increment(1,1); 318 | 319 | // 'view' (alias for 'constant') 320 | // indicates that function does not/cannot change persistent vars 321 | // View function execute locally, not on blockchain 322 | // Noted: constant keyword will soon be deprecated. 323 | uint y = 1; 324 | 325 | function increment(uint x) view returns (uint x) { 326 | x += 1; 327 | y += 1; // this line would fail 328 | // y is a state variable, and can't be changed in a view function 329 | } 330 | 331 | // 'pure' is more strict than 'view' or 'constant', and does not 332 | // even allow reading of state vars 333 | // The exact rules are more complicated, so see more about 334 | // view/pure: 335 | // http://solidity.readthedocs.io/en/develop/contracts.html#view-functions 336 | 337 | // 'Function Visibility specifiers' 338 | // These can be placed where 'view' is, including: 339 | // public - visible externally and internally (default for function) 340 | // external - only visible externally (including a call made with this.) 341 | // private - only visible in the current contract 342 | // internal - only visible in current contract, and those deriving from it 343 | 344 | // Generally, a good idea to mark each function explicitly 345 | 346 | // Functions hoisted - and can assign a function to a variable 347 | function a() { 348 | var z = b; 349 | z(); 350 | } 351 | 352 | function b() { 353 | 354 | } 355 | 356 | // All functions that receive ether must be marked 'payable' 357 | function depositEther() public payable { 358 | balances[msg.sender] += msg.value; 359 | } 360 | 361 | 362 | // Prefer loops to recursion (max call stack depth is 1024) 363 | // Also, don't setup loops that you haven't bounded, 364 | // as this can hit the gas limit 365 | 366 | // B. Events 367 | // Events are notify external parties; easy to search and 368 | // access events from outside blockchain (with lightweight clients) 369 | // typically declare after contract parameters 370 | 371 | // Typically, capitalized - and add Log in front to be explicit and prevent confusion 372 | // with a function call 373 | 374 | // Declare 375 | event LogSent(address indexed from, address indexed to, uint amount); // note capital first letter 376 | 377 | // Call 378 | LogSent(from, to, amount); 379 | 380 | /** 381 | 382 | For an external party (a contract or external entity), to watch using 383 | the Web3 Javascript library: 384 | 385 | // The following is Javascript code, not Solidity code 386 | Coin.LogSent().watch({}, '', function(error, result) { 387 | if (!error) { 388 | console.log("Coin transfer: " + result.args.amount + 389 | " coins were sent from " + result.args.from + 390 | " to " + result.args.to + "."); 391 | console.log("Balances now:\n" + 392 | "Sender: " + Coin.balances.call(result.args.from) + 393 | "Receiver: " + Coin.balances.call(result.args.to)); 394 | } 395 | } 396 | **/ 397 | 398 | // Common paradigm for one contract to depend on another (e.g., a 399 | // contract that depends on current exchange rate provided by another) 400 | 401 | // C. Modifiers 402 | // Modifiers validate inputs to functions such as minimal balance or user auth; 403 | // similar to guard clause in other languages 404 | 405 | // '_' (underscore) often included as last line in body, and indicates 406 | // function being called should be placed there 407 | modifier onlyAfter(uint _time) { require (now >= _time); _; } 408 | modifier onlyOwner { require(msg.sender == owner); _; } 409 | // commonly used with state machines 410 | modifier onlyIfStateA (State currState) { require(currState == State.A); _; } 411 | 412 | // Append right after function declaration 413 | function changeOwner(newOwner) 414 | onlyAfter(someTime) 415 | onlyOwner() 416 | onlyIfState(State.A) 417 | { 418 | owner = newOwner; 419 | } 420 | 421 | // underscore can be included before end of body, 422 | // but explicitly returning will skip, so use carefully 423 | modifier checkValue(uint amount) { 424 | _; 425 | if (msg.value > amount) { 426 | uint amountToRefund = amount - msg.value; 427 | msg.sender.transfer(amountToRefund); 428 | } 429 | } 430 | 431 | 432 | // 6. BRANCHING AND LOOPS 433 | 434 | // All basic logic blocks work - including if/else, for, while, break, continue 435 | // return - but no switch 436 | 437 | // Syntax same as javascript, but no type conversion from non-boolean 438 | // to boolean (comparison operators must be used to get the boolean val) 439 | 440 | // For loops that are determined by user behavior, be careful - as contracts have a maximal 441 | // amount of gas for a block of code - and will fail if that is exceeded 442 | // For example: 443 | for(uint x = 0; x < refundAddressList.length; x++) { 444 | refundAddressList[x].transfer(SOME_AMOUNT); 445 | } 446 | 447 | // Two errors above: 448 | // 1. A failure on transfer stops the loop from completing, tying up money 449 | // 2. This loop could be arbitrarily long (based on the amount of users who need refunds), and 450 | // therefore may always fail as it exceeds the max gas for a block 451 | // Instead, you should let people withdraw individually from their subaccount, and mark withdrawn 452 | // e.g., favor pull payments over push payments 453 | 454 | 455 | // 7. OBJECTS/CONTRACTS 456 | 457 | // A. Calling external contract 458 | contract InfoFeed { 459 | function info() payable returns (uint ret) { return 42; } 460 | } 461 | 462 | contract Consumer { 463 | InfoFeed feed; // points to contract on blockchain 464 | 465 | // Set feed to existing contract instance 466 | function setFeed(address addr) { 467 | // automatically cast, be careful; constructor is not called 468 | feed = InfoFeed(addr); 469 | } 470 | 471 | // Set feed to new instance of contract 472 | function createNewFeed() { 473 | feed = new InfoFeed(); // new instance created; constructor called 474 | } 475 | 476 | function callFeed() { 477 | // final parentheses call contract, can optionally add 478 | // custom ether value or gas 479 | feed.info.value(10).gas(800)(); 480 | } 481 | } 482 | 483 | // B. Inheritance 484 | 485 | // Order matters, last inherited contract (i.e., 'def') can override parts of 486 | // previously inherited contracts 487 | contract MyContract is abc, def("a custom argument to def") { 488 | 489 | // Override function 490 | function z() { 491 | if (msg.sender == owner) { 492 | def.z(); // call overridden function from def 493 | super.z(); // call immediate parent overridden function 494 | } 495 | } 496 | } 497 | 498 | // abstract function 499 | function someAbstractFunction(uint x); 500 | // cannot be compiled, so used in base/abstract contracts 501 | // that are then implemented 502 | 503 | // C. Import 504 | 505 | import "filename"; 506 | import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol"; 507 | 508 | 509 | // 8. OTHER KEYWORDS 510 | 511 | // A. Selfdestruct 512 | // selfdestruct current contract, sending funds to address (often creator) 513 | selfdestruct(SOME_ADDRESS); 514 | 515 | // removes storage/code from current/future blocks 516 | // helps thin clients, but previous data persists in blockchain 517 | 518 | // Common pattern, lets owner end the contract and receive remaining funds 519 | function remove() { 520 | if(msg.sender == creator) { // Only let the contract creator do this 521 | selfdestruct(creator); // Makes contract inactive, returns funds 522 | } 523 | } 524 | 525 | // May want to deactivate contract manually, rather than selfdestruct 526 | // (ether sent to selfdestructed contract is lost) 527 | 528 | 529 | // 9. CONTRACT DESIGN NOTES 530 | 531 | // A. Obfuscation 532 | // All variables are publicly viewable on blockchain, so anything 533 | // that is private needs to be obfuscated (e.g., hashed w/secret) 534 | 535 | // Steps: 1. Commit to something, 2. Reveal commitment 536 | keccak256("some_bid_amount", "some secret"); // commit 537 | 538 | // call contract's reveal function in the future 539 | // showing bid plus secret that hashes to SHA3 540 | reveal(100, "mySecret"); 541 | 542 | // B. Storage optimization 543 | // Writing to blockchain can be expensive, as data stored forever; encourages 544 | // smart ways to use memory (eventually, compilation will be better, but for now 545 | // benefits to planning data structures - and storing min amount in blockchain) 546 | 547 | // Cost can often be high for items like multidimensional arrays 548 | // (cost is for storing data - not declaring unfilled variables) 549 | 550 | // C. Data access in blockchain 551 | // Cannot restrict human or computer from reading contents of 552 | // transaction or transaction's state 553 | 554 | // While 'private' prevents other *contracts* from reading data 555 | // directly - any other party can still read data in blockchain 556 | 557 | // All data to start of time is stored in blockchain, so 558 | // anyone can observe all previous data and changes 559 | 560 | // D. Oracles and External Data 561 | // Oracles are ways to interact with your smart contracts outside the blockchain. 562 | // They are used to get data from the real world, send post requests, to the real world 563 | // or vise versa. 564 | 565 | // Time-based implementations of contracts are also done through oracles, as 566 | // contracts need to be directly called and can not "subscribe" to a time. 567 | // Due to smart contracts being decentralized, you also want to get your data 568 | // in a decentralized manner, otherwise you run into the centralized risk that 569 | // smart contract design matter prevents. 570 | 571 | // To easiest way get and use pre-boxed decentralized data is with Chainlink Data Feeds 572 | // https://docs.chain.link/docs/get-the-latest-price 573 | // We can reference on-chain reference points that have already been aggregated by 574 | // multiple sources and delivered on-chain, and we can use it as a "data bank" 575 | // of sources. 576 | 577 | // You can see other examples making API calls here: 578 | // https://docs.chain.link/docs/make-a-http-get-request 579 | 580 | // And you can of course build your own oracle network, just be sure to know 581 | // how centralized vs decentralized your application is. 582 | 583 | // Setting up oracle networks yourself 584 | 585 | // E. Cron Job 586 | // Contracts must be manually called to handle time-based scheduling; can create external 587 | // code to regularly ping, or provide incentives (ether) for others to 588 | // 589 | 590 | // F. Observer Pattern 591 | // An Observer Pattern lets you register as a subscriber and 592 | // register a function which is called by the oracle (note, the oracle pays 593 | // for this action to be run) 594 | // Some similarities to subscription in Pub/sub 595 | 596 | // This is an abstract contract, both client and server classes import 597 | // the client should implement 598 | contract SomeOracleCallback { 599 | function oracleCallback(int _value, uint _time, bytes32 info) external; 600 | } 601 | 602 | contract SomeOracle { 603 | SomeOracleCallback[] callbacks; // array of all subscribers 604 | 605 | // Register subscriber 606 | function addSubscriber(SomeOracleCallback a) { 607 | callbacks.push(a); 608 | } 609 | 610 | function notify(value, time, info) private { 611 | for(uint i = 0;i < callbacks.length; i++) { 612 | // all called subscribers must implement the oracleCallback 613 | callbacks[i].oracleCallback(value, time, info); 614 | } 615 | } 616 | 617 | function doSomething() public { 618 | // Code to do something 619 | 620 | // Notify all subscribers 621 | notify(_value, _time, _info); 622 | } 623 | } 624 | 625 | // Now, your client contract can addSubscriber by importing SomeOracleCallback 626 | // and registering with Some Oracle 627 | 628 | // G. State machines 629 | // see example below for State enum and inState modifier 630 | 631 | // *** EXAMPLE: A crowdfunding example (broadly similar to Kickstarter) *** 632 | // ** START EXAMPLE ** 633 | 634 | // CrowdFunder.sol 635 | pragma solidity ^0.6.6; 636 | 637 | /// @title CrowdFunder 638 | /// @author nemild 639 | contract CrowdFunder { 640 | // Variables set on create by creator 641 | address public creator; 642 | address payable public fundRecipient; // creator may be different than recipient, and must be payable 643 | uint public minimumToRaise; // required to tip, else everyone gets refund 644 | string campaignUrl; 645 | byte version = "1"; 646 | 647 | // Data structures 648 | enum State { 649 | Fundraising, 650 | ExpiredRefund, 651 | Successful 652 | } 653 | struct Contribution { 654 | uint amount; 655 | address payable contributor; 656 | } 657 | 658 | // State variables 659 | State public state = State.Fundraising; // initialize on create 660 | uint public totalRaised; 661 | uint public raiseBy; 662 | uint public completeAt; 663 | Contribution[] contributions; 664 | 665 | event LogFundingReceived(address addr, uint amount, uint currentTotal); 666 | event LogWinnerPaid(address winnerAddress); 667 | 668 | modifier inState(State _state) { 669 | require(state == _state); 670 | _; 671 | } 672 | 673 | modifier isCreator() { 674 | require(msg.sender == creator); 675 | _; 676 | } 677 | 678 | // Wait 24 weeks after final contract state before allowing contract destruction 679 | modifier atEndOfLifecycle() { 680 | require(((state == State.ExpiredRefund || state == State.Successful) && 681 | completeAt + 24 weeks < now)); 682 | _; 683 | } 684 | 685 | function crowdFund( 686 | uint timeInHoursForFundraising, 687 | string memory _campaignUrl, 688 | address payable _fundRecipient, 689 | uint _minimumToRaise) 690 | public 691 | { 692 | creator = msg.sender; 693 | fundRecipient = _fundRecipient; 694 | campaignUrl = _campaignUrl; 695 | minimumToRaise = _minimumToRaise; 696 | raiseBy = now + (timeInHoursForFundraising * 1 hours); 697 | } 698 | 699 | function contribute() 700 | public 701 | payable 702 | inState(State.Fundraising) 703 | returns(uint256 id) 704 | { 705 | contributions.push( 706 | Contribution({ 707 | amount: msg.value, 708 | contributor: msg.sender 709 | }) // use array, so can iterate 710 | ); 711 | totalRaised += msg.value; 712 | 713 | emit LogFundingReceived(msg.sender, msg.value, totalRaised); 714 | 715 | checkIfFundingCompleteOrExpired(); 716 | return contributions.length - 1; // return id 717 | } 718 | 719 | function checkIfFundingCompleteOrExpired() 720 | public 721 | { 722 | if (totalRaised > minimumToRaise) { 723 | state = State.Successful; 724 | payOut(); 725 | 726 | // could incentivize sender who initiated state change here 727 | } else if ( now > raiseBy ) { 728 | state = State.ExpiredRefund; // backers can now collect refunds by calling getRefund(id) 729 | } 730 | completeAt = now; 731 | } 732 | 733 | function payOut() 734 | public 735 | inState(State.Successful) 736 | { 737 | fundRecipient.transfer(address(this).balance); 738 | LogWinnerPaid(fundRecipient); 739 | } 740 | 741 | function getRefund(uint256 id) 742 | inState(State.ExpiredRefund) 743 | public 744 | returns(bool) 745 | { 746 | require(contributions.length > id && id >= 0 && contributions[id].amount != 0 ); 747 | 748 | uint256 amountToRefund = contributions[id].amount; 749 | contributions[id].amount = 0; 750 | 751 | contributions[id].contributor.transfer(amountToRefund); 752 | 753 | return true; 754 | } 755 | 756 | function removeContract() 757 | public 758 | isCreator() 759 | atEndOfLifecycle() 760 | { 761 | selfdestruct(msg.sender); 762 | // creator gets all money that hasn't be claimed 763 | } 764 | } 765 | // ** END EXAMPLE ** 766 | 767 | 768 | // 10. OTHER NATIVE FUNCTIONS 769 | 770 | // Currency units 771 | // Currency is defined using wei, smallest unit of Ether 772 | uint minAmount = 1 wei; 773 | uint a = 1 finney; // 1 ether == 1000 finney 774 | // Other units, see: http://ether.fund/tool/converter 775 | 776 | // Time units 777 | 1 == 1 second 778 | 1 minutes == 60 seconds 779 | 780 | // Can multiply a variable times unit, as units are not stored in a variable 781 | uint x = 5; 782 | (x * 1 days); // 5 days 783 | 784 | // Careful about leap seconds/years with equality statements for time 785 | // (instead, prefer greater than/less than) 786 | 787 | // Cryptography 788 | // All strings passed are concatenated before hash action 789 | sha3("ab", "cd"); 790 | ripemd160("abc"); 791 | sha256("def"); 792 | 793 | // 11. SECURITY 794 | 795 | // Bugs can be disastrous in Ethereum contracts - and even popular patterns in Solidity, 796 | // may be found to be antipatterns 797 | 798 | // See security links at the end of this doc 799 | 800 | // 12. LOW LEVEL FUNCTIONS 801 | // call - low level, not often used, does not provide type safety 802 | successBoolean = someContractAddress.call('function_name', 'arg1', 'arg2'); 803 | 804 | // callcode - Code at target address executed in *context* of calling contract 805 | // provides library functionality 806 | someContractAddress.callcode('function_name'); 807 | 808 | 809 | // 13. STYLE NOTES 810 | // Based on Python's PEP8 style guide 811 | // Full Style guide: http://solidity.readthedocs.io/en/develop/style-guide.html 812 | 813 | // Quick summary: 814 | // 4 spaces for indentation 815 | // Two lines separate contract declarations (and other top level declarations) 816 | // Avoid extraneous spaces in parentheses 817 | // Can omit curly braces for one line statement (if, for, etc) 818 | // else should be placed on own line 819 | 820 | 821 | // 14. NATSPEC COMMENTS 822 | // used for documentation, commenting, and external UIs 823 | 824 | // Contract natspec - always above contract definition 825 | /// @title Contract title 826 | /// @author Author name 827 | 828 | // Function natspec 829 | /// @notice information about what function does; shown when function to execute 830 | /// @dev Function documentation for developer 831 | 832 | // Function parameter/return value natspec 833 | /// @param someParam Some description of what the param does 834 | /// @return Description of the return value 835 | -------------------------------------------------------------------------------- /ETHEREUM.md: -------------------------------------------------------------------------------- 1 | # Awesome Ethereum (Blockchain) - What's News? 2 | 3 | 4 | Weekly ethereum improvement proposal (eip) updates. 5 | 6 | 7 | Note: For weekly solidity (contract) programming "dev stuff" 8 | updates - see [**NEWS »**](NEWS.md) 9 | 10 | 11 | 12 | ## Week 05/2023 - Monday, January 30th to Sunday, February 5th 13 | 14 | 15 | - Tim Beiko's proposal to fork [ERCs from EIPs repository](https://ethereum-magicians.org/t/proposal-forking-ercs-from-eips-repository/12804) 16 | - [EIP6404](https://github.com/ethereum/EIPs/pull/6404/files): SSZ transactions, receipts and withdrawals 17 | - [ERC6160](https://github.com/ethereum/EIPs/pull/6403/files): Multichain token 18 | 19 | 20 | 21 | ## Week 04/2023 - Monday, January 22th to Sunday, January 29th 22 | 23 | 24 | - [ERC6366](https://github.com/ethereum/EIPs/pull/6366/files): Permission token 25 | - Description: A new token that held the permission of an address in an ecosystem 26 | - Abstract: This EIP offers an alternative to Access Control Lists (ACLs) for granting authorization and enhancing security. Each permission is represented by a single bit in `uint256` from which we can defined up to `256` permissions and `2²⁵⁶` roles. This approach use bitwise operator and bitmask to determine the access right which is much more efficient and flexible than `string` comparison or `keccak()`. We are able to specify the importance of permission based on the bit order. 27 | - [ERC6372](https://eips.ethereum.org/EIPS/eip-6372): Contract clock 28 | - Description: An interface for exposing a contract's clock value and details 29 | - Abstract: Many contracts rely on some clock for enforcing delays and storing historical data. While some contracts rely on block numbers, others use timestamps. There is currently no easy way to discover which time-tracking function a contract internally uses. This EIP proposes to standardize an interface for contracts to expose their internal clock and thus improve composability and interoperability. 30 | - [ERC6381](https://github.com/ethereum/EIPs/pull/6381/files): Emotable extension for non-fungible tokens (NFT)s 31 | - Description: An interface for Non-Fungible Tokens extension allowing for reacting to them using Unicode emojis. 32 | - Abstract: The Emotable Extension for Non-Fungible Tokens standard extends EIP-721 by allowing NFTs to be emoted at. This proposal introduces the ability to react to NFTs using Unicode standardized emoji. 33 | - [EIP6384](https://github.com/ethereum/EIPs/pull/6384/files): Humanly readable offline signatures 34 | - Description: A method for retrieving a human-readable description of EIP-712 typed and structured data. 35 | - Abstract: This EIP introduces the `evalEIP712Buffer` function, which takes an EIP-712 buffer and returns a human-readable text description. 36 | 37 | 38 | 39 | ## Week 03/2023 - Monday, January 16th to Sunday, January 21st 40 | 41 | 42 | - [ERC6299](https://github.com/ethereum/EIPs/pull/6299/files): Lockable tokens 43 | - [ERC6315](https://github.com/ethereum/EIPs/pull/6315/files): ERC2771 Account Abstraction 44 | - [ERC6327](https://github.com/ethereum/EIPs/pull/6327/files): Elastic signature 45 | - [ERC6353](https://github.com/ethereum/EIPs/pull/6353/files): Charity token 46 | - [ERC6357](https://github.com/ethereum/EIPs/pull/6357/files): Single-contract Multicall 47 | - [ERC6358](https://github.com/ethereum/EIPs/pull/6358/files): Omniverse DLT 48 | 49 | 50 | ## Week 02/2023 - Monday, January 9th to Sunday, January 15th 51 | 52 | - [ERC6150](https://github.com/keeganlee/EIPs/blob/80571ca99550c576c807a5ba50ccf25e27f9f21e/EIPS/eip-6150.md): Hierarchical non-fungible tokens (NFT)s 53 | 54 | 55 | 56 | ## Week 01/2023 - Monday, January 2nd to Sunday, January 8th 57 | 58 | 59 | - [EIP6212](https://github.com/ethereum/EIPs/pull/6260/files): Buyable non-fungible tokens (NFTs) on-chain and royalties 60 | - Description: Allowing tokens to be buyable and enforce royalties directly on-Chain 61 | - [EIP6268](https://github.com/ethereum/EIPs/pull/6268/files): Non transferability indicator for ERC1155 62 | - Description: An extension of EIP-1155 for indicating the transferability of the token. 63 | - [EIP6269](https://github.com/ethereum/EIPs/pull/6269/files): Full EVM equivalence 64 | - Description: Canonicalise the definition of Full EVM Equivalence 65 | 66 | 67 | 68 | ## Week 52/2022 - Monday, December 26th to Sunday, January 1st 2023 69 | 70 | 71 | - [EIP6220](https://github.com/ethereum/EIPs/pull/6220/files): Composable NFTs utilizing equipable parts 72 | - [EIP6224](https://github.com/ethereum/EIPs/pull/6224/files): Contracts registry the dependency injector 73 | - [EIP6228](https://github.com/ethereum/EIPs/pull/6228/files): Extreme ЕRС20, meta-transaction token (MTT) 74 | - [EIP6229](https://github.com/ethereum/EIPs/pull/6229/files): Tokenized vaults with lock-in period 75 | - [EIP6239](https://github.com/ethereum/EIPs/pull/6239/files): Semantic soulbound tokens 76 | 77 | 78 | 79 | ## Sources 80 | 81 | Thanks to the Week in Ethereum - EIPs/Standards weekly news updates. 82 | 83 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # Awesome Solidity - What's News? 2 | 3 | Weekly solidity (contract) programming "dev stuff" updates. 4 | 5 | 6 | Bonus: For weekly ethereum improvement proposal (eip) updates - see [**ETHEREUM »**](ETHEREUM.md) 7 | 8 | 9 | 12 | 13 | ## Week 05/2023 - Monday, January 30th to Sunday, February 5th 14 | 15 | 16 | - Solidity [v0.8.18](https://blog.soliditylang.org/2023/02/01/solidity-0.8.18-release-announcement/): Paris default EVM version, adds block.prevrandao & deprecates block.difficulty, adds flag to not append CBOR metadata, deprecates selfdestruct and improves bytecode generation from Yul 17 | - [Codeslaw](https://www.codeslaw.app/): search verified contracts 18 | - [ERC721X](https://github.com/indeliblelabs/contracts/blob/main/src/contracts/extensions/ERC721X.sol): ERC721 extension to auto expire transfer approvals after 30 days 19 | - Guide [to libraries in Solidity](https://medium.com/@MarqyMarq/deep-dive-into-solidity-libraries-e9bd7f9061fb) 20 | - Ape [v0.6.0](https://twitter.com/apeframework/status/1620843786497847296) (Python contract framework): beta support for Multicall3, adds per-function encode/decode methods and run scripts in nested subdirectories 21 | - MatchboxDAO's 0xMonaco race entries: [first](https://github.com/marktoda/monaco), [second](https://typefully.com/gretzke/DTU1xJn), [third](https://twitter.com/NotDeGhost/status/1619845952998887424) & [disqualified bug exploiter](https://twitter.com/zellic_io/status/1620844495226179586) 22 | - Secureum RACE #14: [8 question Solidity quiz & answers](https://ventral.digital/posts/2023/1/30/race-14-of-the-secureum-bootcamp-epoch-infinity) 23 | - Capture the Flag (CTF) solutions using Ape & Vyper: [Ethernaut](https://github.com/0xJCN/Ethernaut-CTF), [Damn vulnerable DeFi](https://github.com/0xJCN/Damn-Vulnerable-DeFi-V3-CTF) & [EthernautDAO](https://github.com/0xJCN/EthernautDAO-Challenges) 24 | - [Guide to using SMTChecker](https://www.truscova.com/blog_article_5.php) with Hardhat 25 | - [Halmos](https://github.com/a16z/halmos#readme): symbolic testing reusing Foundry tests for formal verification 26 | - [Wagmi CLI](https://twitter.com/wagmi_sh/status/1620097176738357248) (React hooks): generate code, connect to Foundry/Hardhat projects & create plugins 27 | - [Universal bridge](https://github.com/ZeframLou/universal-bridge#readme): common interface to send a message to a supported network using official bridges 28 | - [zkLLVM compiler](https://blog.nil.foundation/2023/02/02/circuit-compiler.html): circuit compiler for languages such as C/C++ 29 | - [Spartan-ecdsa](https://personaelabs.org/posts/spartan-ecdsa/): verify secp256k1 ECDSA signatures in zk, proofs in browser in 5 seconds 30 | - [In-browser recursive proving & verification](https://twitter.com/nibnalin/status/1621059453570412544) added to Nova & Nova Scotia 31 | 32 | 33 | 34 | 37 | 38 | ## Week 04/2023 - Monday, January 22th to Sunday, January 29th 39 | 40 | 41 | - Foundry: 42 | - ChugSplash [Foundry](https://github.com/chugsplash/chugsplash-foundry#readme): deploy & manage upgradeable contracts, upgrade OpenZeppelin Transparent proxies, supports mainnet & Optimism 43 | - [Deal cheat code](https://twitter.com/paulrberg/status/1619059764180434944) mints ERC20 tokens in tests 44 | - [EVM call stipend](https://twitter.com/wadealexc/status/1619030019803848704) (2300 gas) explainer 45 | - OpenZeppelin [proposal to mitigate ERC4626 inflation attacks](https://ethereum-magicians.org/t/address-eip-4626-inflation-attacks-with-virtual-shares-and-assets/12677) with virtual assets & shares 46 | - [Sparse-arr-lib](https://github.com/clabby/sparse-arr-lib#readme): Solidity library for sparse arrays, work in progress 47 | - [Optimizing using Yul](https://medium.com/@MarqyMarq/using-yul-to-optimize-gas-costs-b4feccdb5172) via example rock, paper & scissors contracts 48 | - Samczsun's [signature database](https://twitter.com/samczsun/status/1618161664624594945): exportable, add to canonical list via GitHub 49 | - [Clipshot](https://clipshot.xyz/): ERC1155 token holder snapshots as CSV 50 | - [Hydralisk](https://github.com/paulpierre/hydralisk#readme): Python CLI for bulk wallet creation 51 | - [Walk through of building bear traps](https://paulbrower.codes/posts/bear-traps-in-the-dark-forest/) for MEV bot front-runners 52 | - DamnVulnerableDefi [ABI smuggling solution](https://medium.com/@mattaereal/damnvulnerabledefi-abi-smuggling-challenge-walkthrough-plus-infographic-7098855d49a) 53 | - [Uniswap v3 math](https://uniswap.org/blog/uniswap-v3-math-primer) explainer 54 | 55 | 56 | 57 | 60 | 61 | ## Week 03/2023 - Monday, January 16th to Sunday, January 21st 62 | 63 | 64 | - Foundry: 65 | - Foundry [best practices](https://twitter.com/msolomon44/status/1616072891820539904) 66 | - forge-std [v1.3.0](https://github.com/foundry-rs/forge-std/releases/tag/v1.3.0): InvariantTest helper contract, Multicall3 interface & getTokenBalances helper, StdChains chain alias, parseJson & assumePayable cheat codes and decimal assertions 67 | - Invariant testing: [example](https://github.com/lucas-manuel/invariant-example/#readme) repo to experiment, also see Maple Finance invariant tests 68 | - [forge doc](https://twitter.com/r_krasiuk/status/1615444642195202055): documentation generator using natspec, outputs markdown 69 | - Solidity [preview of user-defined operators](https://forum.soliditylang.org/t/feature-preview-user-defined-operators/1435) in upcoming v0.8.18 70 | - Fe language [bountiful round 2](https://blog.fe-lang.org/posts/bountiful-round-2/) bug bounty contest 71 | - Beginners guide to [Yul (intermediate language)](https://medium.com/@markjonathas/beginners-guide-to-yul-12a0a18095ef) 72 | - [Guide to contract decompilation](https://jbecker.dev/research/diving-into-decompilation/), as implemented by heimdall-rs (decompiler) 73 | - [Solidity-merkle-trees](https://github.com/polytope-labs/solidity-merkle-trees#readme): Solidity library to verify multi-proofs of Merkle trees 74 | - [ERC5267 demo website](https://eip5267.vercel.app/) to retrieve ERC712 domain 75 | - [The Graph](https://twitter.com/graphprotocol/status/1615772852745027594) adds support for Arbitrum & Optimism 76 | 77 | 78 | 81 | 82 | 83 | ## Week 02/2023 - Monday, January 9th to Sunday, January 15th 84 | 85 | 86 | - Hardhat and Foundry plugin [v1](https://github.com/NomicFoundation/hardhat/releases/tag/%40nomicfoundation/hardhat-foundry%401.0.0) 87 | - Foundry toolchain now [caches RPC calls in CI flows](https://github.com/foundry-rs/foundry-toolchain) 88 | - If you've deployed a contract to Mainnet, Goerli, or Sepolia before Nov 15, 2022, you can [claim 10 goerli + 10 sepolia eth](https://grabteeth.xyz/) 89 | - [Chugsplash](https://twitter.com/ChugSplash_io/status/1611598563301007360): tool to deploy and upgrade smart contracts securely 90 | - [Turborepo starter kit](https://github.com/alexallah/ethereum-healthmon): NextJS, WAGMI, Ethers, Tailwind, Hardhat, Typechain 91 | - Paul Berg on solving [stack too deep](https://twitter.com/PaulRBerg/status/1612043506545033218) 92 | - Now over [225 contracts to fork and easily deploy](https://www.cookbook.dev/) on Cookbook.dev 93 | - [Node health monitoring](https://github.com/alexallah/ethereum-healthmon) tool 94 | 95 | 96 | 97 | 100 | 101 | ## Week 01/2023 - Monday, January 2nd to Sunday, January 8th 102 | 103 | 104 | - [Solidity compiler appends encoded IPFS hash of contract metadata](https://mirror.xyz/joenrv.eth/DdbK6GR-CkeYxHoU8sKl0AFYbGeQwZcvCM5Qvzipr0g) to bytecode for verification 105 | - Guide to [using PrevRandao](https://soliditydeveloper.com/prevrandao) 106 | - Paul Berg: [Solidity supports functions as parameters](https://twitter.com/paulrberg/status/1609917508223475712), useful in testing e.g. [Seaport](https://github.com/ProjectOpenSea/seaport/blob/1.2/test/foundry/FulfillOrderTest.t.sol#L64-L71) 107 | - [EVM quirks](https://twitter.com/jtriley_eth/status/1609216690147020803) and how they are handled in Solidity & Vyper 108 | - [Setup remixd](https://jamesbachini.com/remixd-tutorial/) to use Remix with local filesystem 109 | - Capture the Flag (CTFs): 110 | - [Mr Steal Yo Crypto](https://mrstealyocrypto.xyz/), uses Hardhat 111 | - Making of [HappyNewYear CTF](https://mirror.xyz/vicnaum.eth/reNCgNs7e0rDNx7h8Yt0a9xbS7wFss4950Dl8tYr2kY) 112 | - Damn Vulnerable DeFi [backdoor solution](https://stermi.xyz/blog/damn-vulnerable-defi-challenge-11-solution-backdoor) 113 | - [Shop puzzle](https://twitter.com/0xCygaar/status/1610114831000170496) & solution 114 | - Secureum bootcamp [race-13 quiz solution](https://ventral.digital/posts/2023/1/3/race-13-of-the-secureum-bootcamp-epoch) 115 | - [TurboETH](https://twitter.com/KamesGeraghty/status/1609872647965261825): dapp build system, app template, ERC20 & ERC721 components & hooks, beta 116 | - Use TrueBlocks to [find all contracts created by an address](https://tjayrush.medium.com/recipe-factories-ce78fa4c5f5b) 117 | - [Guide to equivalence checking](https://www.truscova.com/blog_article_2.php) Solidity functionality with a reference implementation using Z3 theorem prover 118 | - [UniRep protocol](https://mirror.xyz/privacy-scaling-explorations.eth/FCVVfy-TQ6R7_wavKj1lCr5dd1zqRvwjnDOYRM5NtsE): private & non-repudiable reputation system 119 | 120 | 121 | 124 | 125 | ## Week 52/2022 - Monday, December 26th to Sunday, January 1st 2023 126 | 127 | 128 | - Foundry [Chisel](https://github.com/foundry-rs/foundry/tree/master/chisel#readme): Solidity REPL 129 | - [Etherscan contract verification API](https://twitter.com/etherscan/status/1608796718677753858) adds failure message 130 | - [Uniswap poor oracle](https://github.com/timeless-fi/uniswap-poor-oracle#readme): flash loan proof Uniswap v3 price-out-of-range oracle 131 | - [Norswap on ERC2535 (Diamonds)](https://twitter.com/norswap/status/1607425088491753472): only use to circumvent contract size limitations 132 | - [Fallback](https://github.com/nathanhleung/fallback#readme): create web apps in Solidity, proof of concept 133 | - [Huff-immutables](https://github.com/vicnaum/huff-immutables#readme): constructor-initialized immutables in Huff 134 | - VSCode Solidity Inspector [v0.0.3](https://github.com/PraneshASP/vscode-solidity-inspector/releases/tag/v0.0.3): view contract storage layout 135 | - Understanding [EVM instruction boundaries](https://mirror.xyz/vicnaum.eth/zJX21EV6bjrPcL_8fnI-0zoChvBw-ZscbL7S7inroro) plus an [EVM regex decompiler](https://gist.github.com/vicnaum/492d9ccfb66dc0f50b1fd8f99239f6a7) (Perl compatible regex) 136 | - [Noble-curves](https://github.com/paulmillr/noble-curves#readme): elliptic curves in JavaScript, zero-dependencies 137 | - Wagmi (React hooks) [v0.10.0](https://github.com/wagmi-dev/wagmi/releases/tag/wagmi%400.10.0): WalletConnect v2 support and useWatchPendingTransactions hook 138 | - [ENS Profile API](https://blog.indexing.co/posts/6xGR3GSQ2lY5Lpo0WRWJlqMutSt241RxdOsDg_ABXRo): access via GraphQL 139 | 140 | 141 | 142 | 143 | 146 | 147 | ## Week 51/2022 - Monday, December 19th to Sunday, December 25th 148 | 149 | 150 | 151 | ## Week 50/2022 - Monday, December 12th to Sunday, December 18th 152 | 153 | 154 | ## Week 49/2022 - Monday, December 5th to Sunday, December 11th 155 | 156 | 157 | ## Week 48/2022 - Monday, November 28th to Sunday, December 4th 158 | 159 | 160 | ## Week 47/2022 - Monday, November 21st to Sunday, November 27th 161 | 162 | 163 | ## Week 46/2022 - Monday, November 14th to Sunday, November 20th 164 | 165 | 166 | ## Week 45/2022 - Monday, November 7th to Sunday, November 13rd 167 | 168 | 169 | ## Week 44/2022 - Monday, October 31st to Sunday, November 6th 170 | 171 | 172 | ## Week 43/2022 - Monday, October 24th to Sunday, October 30th 173 | 174 | 175 | ## Week 42/2022 - Monday, October 17th to Sunday, October 23rd 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | ## Sources 184 | 185 | Thanks to the Week in Ethereum - Stuff For (Solidity) Developers 186 | weekly news updates. 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Awesome Solidity (Contract) Programming Language & Tools 2 | 3 | 4 | ## What's News? 5 | 6 | For weekly solidity (contract) programming "dev stuff" updates - see [**NEWS »**](NEWS.md) 7 | 8 | 9 | Bonus: For weekly ethereum improvement proposal (eip) updates - see [**ETHEREUM »**](ETHEREUM.md) 10 | 11 | 12 | 13 | ## New to Solidity? 14 | 15 | _Official_ 16 | 17 | Solidity Language @ 18 | 19 | - Read the Docs @ 20 | - Blog @ 21 | - Forum @ 22 | - Source @ 23 | 24 | 25 | 26 | _More_ 27 | 28 | Solidity by Example @ 29 | 30 | Learn X in Y Minutes (Where X=Solidity) @ 31 | 32 | 33 | 34 | ## Alternative Contract-Oriented Programming Languages 35 | 36 | ### Higher-Level 37 | 38 | **Fe** - the syntax is inspired by Python and Rust. It is easy to learn, even for those who have never dealt with the ethereum virtual machine (evm) before; designed to be safe and equipped with the tooling needed to validate contracts; uses the same intermediate language as Solidity (YUL), making it a great choice not only for the ethereum mainnet, but also for (upcoming) layer two chains. 39 | 40 | - web @ 41 | - docs @ 42 | - source @ 43 | 44 | **Vyper** - a more recently developed language, similar to Serpent and again with Python-like syntax. 45 | Intended to get closer to a pure-functional Python-like language than Serpent, but not to replace Serpent. 46 | 47 | - docs @ 48 | - source @ 49 | 50 | **Secure Ruby / Small, Smart, Secure, Safe, Solid & Sound (S6) Ruby (sruby / s6 ruby)** - the ruby programming language for contract / transaction scripts on the blockchain world computer - yes, it's just ruby; see the [**red paper »**](https://github.com/s6ruby/redpaper) 51 | 52 | - source @ 53 | - talks 54 | - Code Your Own (Crypto Blockchain) Contracts w/ Ruby (sruby), Universum & Co @ 55 | 56 | 57 | 58 | 59 | _Historic_ 60 | 61 | **Serpent** - a procedural (imperative) programming language with a syntax similar to Python. Can also be used to write functional (declarative) code, though it is not entirely free of side effects. 62 | 63 | - source @ 64 | 65 | **Bamboo** - a language influenced by Erlang, with explicit state transitions and without iterative flows (loops). Intended to reduce side effects and increase auditability. 66 | 67 | - source @ 68 | 69 | 70 | ### Low-Level ("Assembly-Like") 71 | 72 | **YUL** - official "intermediate" assembly language for the ethereum virtual machine (evm) 73 | 74 | 75 | > Yul (previously also called JULIA or IULIA) is an intermediate language that can be compiled to bytecode for different backends. 76 | > 77 | > It can be used in stand-alone mode and for "inline assembly" inside Solidity. 78 | > The compiler uses Yul as an intermediate language in the IR-based code generator 79 | > ("new codegen" or "IR-based codegen"). 80 | > Yul is a good target for high-level optimisation stages that can benefit all target platforms equally. 81 | 82 | - docs @ 83 | 84 | 85 | **Huff** - a low level "intermediate" assembly language for the ethereum virtual machine (evm) 86 | 87 | - web @ 88 | - docs @ 89 | - source @ 90 | 91 | 92 | _Historic_ 93 | 94 | **Low-level Lisp-like Language / Lisp Like Language (LLL)** - a functional (declarative) programming language, with Lisp-like syntax. It was the first "intermediate" assembly language for ethereum contracts. 95 | 96 | - docs @ 97 | 98 | 99 | 100 | ### More / Misc 101 | 102 | **Cairo** - a STARK-based turing-complete language for writing provable programs on blockchain. 103 | 104 | - web @ 105 | - docs @ 106 | - source @ 107 | 108 | 109 | 110 | 111 | ## Contract (Source Code) Verification Tools & Services 112 | 113 | ### Sourcify 114 | 115 | > Sourcify enables transparent and human-readable smart contract interactions through automated Solidity contract verification, 116 | > contract metadata, and NatSpec comments. 117 | 118 | - web @ 119 | - docs @ 120 | - source @ 121 | 122 | 123 | 124 | ### Etherscan Verify (& Publish Contract Source Code) 125 | 126 | - docs @ 127 | 128 | 129 | ### Codeslaw (Verified Contract Search) 130 | 131 | > Codeslaw is a code search engine for verified contracts on ethereum and beyond 132 | > to help developers find and learn from verified and live contracts. 133 | > Verified contracts come from the following sources: (1) Etherscan, (2) Tin Tin's Contract Sanctuary, (3) Sourcify 134 | 135 | - web @ 136 | 137 | 138 | 139 | 140 | ## Application Binary Interface (ABI) Specs, Tests, Tools & Services 141 | 142 | 143 | ### (Method) Signature Databases / Lookups 144 | 145 | 146 | 147 | 148 | ## More Awesome Awesomeness 149 | 150 | _A curated list of more awesome lists._ 151 | 152 | 153 | - [**Awesome Solidity**](https://github.com/bkrem/awesome-solidity) by Ben Kremer - a sorted a-to-z lists of solidity goodies 154 | 155 | 156 | 157 | ## Meta 158 | 159 | **License** 160 | 161 | ![](https://publicdomainworks.github.io/buttons/zero88x31.png) 162 | 163 | The awesome list is dedicated to the public domain. Use it as you please with no restrictions whatsoever. 164 | --------------------------------------------------------------------------------