summaryrefslogtreecommitdiffhomepage
path: root/vyper.html.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'vyper.html.markdown')
-rw-r--r--vyper.html.markdown871
1 files changed, 0 insertions, 871 deletions
diff --git a/vyper.html.markdown b/vyper.html.markdown
deleted file mode 100644
index dd319ae5..00000000
--- a/vyper.html.markdown
+++ /dev/null
@@ -1,871 +0,0 @@
----
-language: Vyper
-filename: learnVyper.vy
-contributors:
- - ["Kenny Peluso", "kennyp.herokuapp.com"]
----
-
-> The content of this document is largely inspired by ["Learn Solidity in Y Minutes"](https:#github.com/adambard/learnxinyminutes-docs/blob/master/solidity.html.markdown)
-
-Vyper lets you program on [Ethereum](https:#www.ethereum.org/), a
-blockchain-based virtual machine that allows the creation and
-execution of smart contracts, without requiring centralized or trusted parties. It was
-designed to improve upon Solidity, another smart contract language for Ethereum, by
-limiting unsafe practices and enhancing readability; Vyper seeks to optimize the
-security and auditability of smart contracts.
-
-Vyper is an experimental, statically typed, contract programming language meant to
-resemble Python. Like objects in OOP, each contract contains state variables, functions,
-and common data types. Contract-specific features include event notifiers for listeners,
-and custom global variables, global constants.
-
-Some Ethereum contract examples include crowdfunding, voting, and blind auctions.
-
----
-
-## Table of Contents
-
-- Intro
-- Example
-1. Data types and associated methods
-2. Data structures
-3. Simple operators
-4. Global variables of note
-5. Functions and more
- a. functions
- b. events
-6. Branching and loops
-7. Objects/contracts
- a. calling external contracts
- b. ERC20 built-in
- c. following an interface
-8. Other keywords
- a. selfdestruct
-9. Contract design notes
- a. obfuscation
- b. storage optimization
- c. data access in blockchain
- d. cron job
- e. observer pattern
-10. Security
-11. Style notes
-12. Natspec comments
-- Other documents
-
----
-
-## Intro
-
-From [the docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf)
-the foundational tenants of Vyper are:
-
-1. *Security*
-2. *Language and compiler simplicity*
-3. *Auditability*
-
-This allows for the following features:
-
-1. *Bounds and overflow checking*
- - On the arithmetic and array level
- - There are no dynamic arrays in Vyper
-2. *Support for signed integers and decimal fixed point numbers*
-3. *Decidability* - You can always compute precise upper bound on gas cost
-4. *Strong typing* - for built-in and custom types
-5. *Small and understandable compiler code*
-6. *Limited support for pure functions*
- - Anything marked `@constant` is not allowed to change the state
-
-Following the principles and goals, Vyper does not provide the following features:
-
-1. *Modifiers* (defining parts of functions elsewhere)
-2. *Class inheritance*
-3. *Inline assembly*
-4. *Function overloading*
-5. *Operator overloading*
-6. *Recursive calling*
-7. *Infinite-length loops*
-8. *Binary fixed point* (decimal fixed point is used for its exactness)
-
-WITH THE RAPID CHANGES IN ETHEREUM, THIS DOCUMENT IS UNLIKELY TO STAY UP TO
-DATE, SO YOU SHOULD FOLLOW THE LATEST VYPER DOCS AND ETHEREUM BLOG FOR THE LATEST.
-ALL CODE HERE IS PROVIDED AS IS, WITH SUBSTANTIAL RISK OF ERRORS OR DEPRECATED CODE
-PATTERNS.
-
-This document primarily discusses syntax, and so excludes many
-popular design patterns.
-
-As Vyper and Ethereum are under active development, experimental or beta
-features are typically marked, and subject to change. Pull requests welcome.
-
-This document describes Vyper version `0.1.0-beta.8`.
-
-*All of the following code exists for educational purposes only!*
-*None of the following code should be used in production as-is!*
-
-## Example
-
-```python
-# First, a simple todo list contract
-# Implements CRUD operations for tasks
-
-# todo.vy (note .vy extension)
-### **** START EXAMPLE **** ###
-
-# Start with Natspec comment
-# used for documentation
-
-# @title SimpleBank v1
-# @author kennyp
-# @notice This is a simple bank.
-
-# Vyper contracts must obey a particular order:
-# struct -> interface -> events -> globals and constants -> functions
-# Additionally, like Python, Vyper functions must be defined in the file
-# before they're called.
-
-# Structs
-
-struct Task:
- done: bool
- deleted: bool
- task: string[100]
- metadata: bytes32
-
-# Interfaces
-
-contract AnotherContract():
- def fetch() -> bytes32: constant
- def inform(_taskId: uint256, _status: uint256) -> bool: modifying
-
-# Events
-
-# Events - publicize actions to external listeners
-# `indexed` means that it's easier to search/filter on this field
-TaskStatus: event({_taskId: indexed(uint256), _status: uint256})
-
-# Global Variables
-
-# State variables are values which are permanently stored in contract storage
-# State vars consist of any value persisting beyond any function's scope
-# and are permanently stored in contract storage
-
-# You can define your own, custom, unmutable constants
-CREATED: constant(uint256) = 0
-COMPLETED: constant(uint256) = 1
-DELETED: constant(uint256) = 2
-
-# The `public` built-in allows for this address to be read externally
-# without defining a `get()` constant function
-owner: public(address)
-other: public(address)
-
-# uint256 means "unsigned positive integer between 0 and 2^256 - 1"
-# Overflow protection is built-in to Vyper
-taskCount: uint256
-tasks: map(uint256, Task) # dictionary: key=uint256, value: Task struct
-
-# Private Functions
-
-# Start each function with Pythonic decorators
-# These decorators resemble Natspec but are actually enforced by Vyper's compiler
-# These decorators are:
-# @public XOR @private (either one or the other)
-# @public (if any contract/user can call it)
-# @private (if only internal functions can call it)
-# @payable (if the function is payable i.e. accepting ETH)
-# @constant (if the function is not modifying anything on-chain)
-@private
-def _changeTaskStatus( \
- _sender: address, \
- _taskId: uint256, \
- _status: uint256, \
- ):
- # backslashes (\) allow for multi-line code
- # Natspec comments are particularly helpful for documentation and readability
- # Natspec can be included using familiar Pythonic docstring syntax
- """
- @notice
- @dev `_sender` MUST be `self.owner`
- @param _sender Who is triggering this function
- @param _task The description of the task (only useful when task added)
- """
- # NOTE: Private functions do not have access to `msg.sender`
- # SIDE NOTE: `msg.sender` refers to whoever immediately called the function of
- # immediate scope. In other words, if I call a function that calls another
- # in-contract, public function, then `msg.sender` turns from my address to
- # the address of the current contract.
- assert _sender == self.owner # failed assertions cause calls/transactions to fail
- # Note that unlike Solidity, `self.` is required to query the contract's state
- # Control flow is Pythonic, as is much of Vyper:
- _task: string[100] # initialized to default value
- _data: bytes32 = sha3(convert(_sender, bytes32)) # owner is obfuscated (but still visible in logs)
- if _status == CREATED: # control flow mimics python
- # How a new struct is instantiated:
- self.tasks[_taskId] = Task({ \
- done: False, deleted: False, task: _task, metadata: _data \
- })
- elif _status == COMPLETED:
- # Modifying an existing struct:
- self.tasks[_taskId].done = True
- elif _status == DELETED:
- self.tasks[_taskId].deleted = True
- AnotherContract(self.other).inform(_taskId, _status) # modifying external call
- log.TaskStatus(_taskId, _status) # emit an event
-
-# Public Functions
-
-# Pythonic constructor - can receive none or many arguments
-@public
-def __init__(_owner: address, _other_contract: address):
- """
- @dev Called once and only upon contract depoyment
- """
- self.owner = _owner
- self.other = _other_contract
-
-# NOTE: Pythonic whitespace rules are mandated in Vyper
-
-@public
-def addTask(_task: string[100]) -> uint256:
- """
- @notice Adds a task to contract
- @param _task Description of task
- @return Id of newly minted task
- """
- # msg.sender gives the address of who/what contract is calling this function
- self._changeTaskStatus(msg.sender, self.taskCount, CREATED)
- self.tasks[self.taskCount].task = _task
- self.taskCount += 1
- return self.taskCount - 1
-
-@public
-def addSpecialTask(_task: string[100]) -> uint256:
- """
- @notice Adds a task with metadata pulled from elsewhere
- @param _task Description of task
- @return Id of newly minted task
- """
- self._changeTaskStatus(msg.sender, self.taskCount, CREATED)
- self.tasks[self.taskCount].task = _task
- self.tasks[self.taskCount].metadata = AnotherContract(self.other).fetch()
- self.taskCount += 1
- return self.taskCount - 1
-
-@public
-def completeTask(_taskId: uint256):
- """
- @notice Marks a task as "completed"
- @param _taskId Id of task to complete
- """
- self._changeTaskStatus(msg.sender, _taskId, COMPLETED)
-
-@public
-def deleteTask(_taskId: uint256):
- """
- @notice Adds a task to contract
- @param _taskId Id of task to delete
- """
- self._changeTaskStatus(msg.sender, _taskId, DELETED)
-
-@public
-@constant # allows function to run locally/off blockchain
-def getTask(_taskId: uint256) -> string[100]:
- """
- @notice Getter for a task's description
- @param _taskId Id of task with desired description
- @return Description of task
- """
- return self.tasks[_taskId].task
-
-### **** END EXAMPLE **** ###
-
-
-# Now, the basics of Vyper
-
-
-# ---
-
-
-# 1. DATA TYPES AND ASSOCIATED METHODS
-# uint256 used for currency amount and for dates (in unix time)
-x: uint256
-
-# int of 128 bits, cannot be changed after contract deployment
-# with 'constant', compiler replaces each occurrence with actual value
-a: constant(int128) = 5
-
-# All state variables (those outside a function)
-# are by default 'internal' and accessible inside contract
-# Need to explicitly set to 'public' to allow external contracts to access
-# A getter is automatically created, but NOT a setter
-# Can only be called in the contract's scope (not within functions)
-# Add 'public' field to indicate publicly/externally accessible
-a: public(int128)
-
-# No random functions built in, use other contracts for randomness
-
-# Type casting is limited but exists
-b: int128 = 5
-x: uint256 = convert(b, uint256)
-
-# Types of accounts:
-# Contract Account: f(creator_addr, num_transactions)=address set on contract creation
-# External Account: (person/external entity): f(public_key)=address
-
-# Addresses - An address type can hold an Ethereum address which
-# equates to 20 bytes or 160 bits. It returns in hexadecimal notation
-# with a leading 0x. No arithmetic allowed
-owner: public(address)
-
-# Members can be invoked on all addresses:
-owner.balance # returns balance of address as `wei_value`
-owner.codesize # returns code size of address as `int128`
-owner.is_contract # `True` if Contract Account
-
-# All addresses can be sent ether via `send()` built-in
-@public
-@payable
-def sendWei(any_addr: address):
- send(any_addr, msg.value)
-
-# Bytes available
-a: bytes[2]
-b: bytes[32]
-c: bytes32
-# `b` and `c` are 2 different types
-
-# Bytes are preferable to strings since Vyper currently offers better
-# support for bytes i.e. more built-ins to deal with `bytes32`, `bytes32`
-# can be returned from functions and strings[] can't be, UTF8 (string encoding)
-# uses more storage, etc.
-
-# There are no dynamically sized bytes, similar to how there are no
-# dynamic arrays
-
-# Fixed-size byte arrays (Strings)
-a: string[100]
-b: string[8]
-c: string[108] = concat(a, b) # check the latest docs for more built-ins
-
-# Time
-t1: timedelta
-t2: timestamp
-# Both types are built-in "custom type" variants of `uint256`
-# `timedelta` values can be added but not `timestamp` values
-
-# Money
-m: wei_value
-# Also has the base type `uint256` like `timestamp` and `timedelta`
-# 1 unit of WEI (a small amount of ETH i.e. ether)
-
-# Custom types
-# specify units used in the contract:
-units: {
- cm: "centimeter",
- km: "kilometer"
-}
-# usage:
-a: int128(cm)
-b: uint256(km)
-
-# BY DEFAULT: all values are set to 0 on instantiation
-
-# `clear()` can be called on most types
-# Does NOT destroy value, but sets value to 0, the initial value
-
-
-# ---
-
-
-# 2. DATA STRUCTURES
-# Arrays
-bytes32[5] nicknames; # static array
-bytes32[] names; # dynamic array
-uint newLength = names.push("John"); # adding returns new length of the array
-# Length
-names.length; # get length
-names.length = 1; # lengths can be set (for dynamic arrays in storage only)
-
-# Multidimensional Arrays
-# At initialization, array dimensions must be hard-coded or constants
-# Initialize a 10-column by 3-row, multidimensional fixed array
-ls: (uint256[10])[3] # parentheses are optional
-@public
-def setToThree():
- # Multidimensional Array Access and Write
- # access indices are reversed
- # set element in row 2 (3rd row) column 5 (6th column) to 3
- self.ls[2][5] = 3
-
-# Dictionaries (any simple type to any other type including structs)
-theMap: map(uint256, bytes32)
-theMap[5] = sha3("charles")
-# theMap[255] result is 0, all non-set key values return zeroes
-# To make read public, make a getter that accesses the mapping
-@public
-def getMap(_idx: uint256) -> bytes32:
- """
- @notice Get the value of `theMap` at `_idx`
- """
- return self.theMap[_idx]
-
-self.getMap(5) # returns sha3("charles") in bytes32
-
-# Nested mappings
-aMap: map(address, map(address, uint256))
-# NOTE: Mappings are only allowed as state variables
-# NOTE: Mappings are not iterable; can only be accessed
-
-# To delete (reset the mapping's value to default at a key)
-clear(balances["John"])
-clear(balances); # sets all elements to 0
-
-# Unlike other languages, CANNOT iterate through all elements in
-# mapping, without knowing source keys - can build data structure
-# on top to do this
-
-# Structs
-struct Struct:
- owner: address
- _balance: uint256 # balance is a reserved keyword, is a member for addresses
-
-exampleStruct: Struct
-
-@public
-def foo() -> uint256:
- self.exampleStruct = Struct({owner: msg.sender, _balance: 5})
- self.exampleStruct._balance = 10
- self.exampleStruct._balance = 5 # set to new value
- clear(self.exampleStruct._balance)
- clear(self.exampleStruct)
- return self.exampleStruct._balance
-
-
-# Data locations: Memory vs. storage vs. calldata - 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 func params
-# stack holds small local variables
-
-# for most types, can explicitly set which data location to use
-
-
-# ---
-
-
-# 3. SIMPLE OPERATORS
-# Comparisons, bit operators and arithmetic operators are provided
-# exponentiation: **
-# modulo: %
-# maximum: max(x, y)
-# AND: bitwise_and(x, y)
-# bitwise shift: shift(x, _shift)
-# where x,y are uint256
-# _shift is int128
-
-# 4. GLOBAL VARIABLES OF NOTE
-# ** self **
-self # address of contract
-# often used at end of contract life to transfer remaining balance to party:
-self.balance # balance of current contract
-self.someFunction() # calls func externally via call, not via internal jump
-
-# ** msg - Current message received by the contract **
-# Ethereum programmers take NOTE: this `msg` object is smaller than elsewhere
-msg.sender # address of sender
-msg.value # amount of ether provided to this contract in wei, the function should be marked `@payable`
-msg.gas # remaining gas
-
-# ** tx - This transaction **
-# Ethereum programmers take NOTE: this `tx` object is smaller than elsewhere
-tx.origin # address of sender of the transaction
-
-# ** block - Information about current block **
-block.timestamp # time at current block (uses Unix time)
-# Note that `block.timestamp` can be manipulated by miners, so be careful
-block.number # current block number
-block.difficulty # current block difficulty
-
-# ** storage - Persistent storage hash **
-storage['abc'] = 'def'; # maps 256 bit words to 256 bit words
-
-
-# ---
-
-
-# 5. FUNCTIONS AND MORE
-
-# A. FUNCTIONS
-# Simple function
-function increment(uint x) returns (uint) {
- x += 1;
- return x;
-}
-
-# Functions can return many arguments
-@public
-@constant
-def increment(x: uint256, y: uint256) -> (uint256, uint256):
- x += 1
- y += 1
- return (x, y)
-
-# Call previous function
-@public
-@constant
-def willCall() -> (uint256, uint256):
- return self.increment(1,1)
-
-# One should never have to call a function / hold any logic outside
-# outside the scope of a function in Vyper
-
-# '@constant'
-# indicates that function does not/cannot change persistent vars
-# Constant function execute locally, not on blockchain
-y: uint256
-@public
-@constant
-def increment(x: uint256) -> uint256:
- x += 1
- y += 1 # this line would fail
- # y is a state variable => can't be changed in a constant function
-
-
-# 'Function Decorators'
-# Used like python decorators but are REQUIRED by Vyper
-# @public - visible externally and internally (default for function)
-# @private - only visible in the current contract
-# @constant - doesn't change state
-# @payable - receive ether/ETH
-# @nonrentant(<unique_key>) - Function can only be called once, both externally
-# and internally. Used to prevent reentrancy attacks
-
-# Functions hare not hoisted
-# Functions cannot be assigned to a variable
-# Functions cannot be recursive
-
-# All functions that receive ether must be marked 'payable'
-@public
-@payable
-def depositEther():
- self.balances[msg.sender] += msg.value
-
-
-# B. EVENTS
-# Events are notify external parties; easy to search and
-# access events from outside blockchain (with lightweight clients)
-# typically declare after contract parameters
-
-# Declare
-LogSent: event({_from: indexed(address), address: indexed(_to), _amount: uint256})
-# Call
-log.LogSent(from, to, amount)
-
-/**
-For an external party (a contract or external entity), to watch using
-the Web3 Javascript library:
-
-# The following is Javascript code, not Vyper code
-Coin.LogSent().watch({}, '', function(error, result) {
- if (!error) {
- console.log("Coin transfer: " + result.args.amount +
- " coins were sent from " + result.args.from +
- " to " + result.args.to + ".");
- console.log("Balances now:\n" +
- "Sender: " + Coin.balances.call(result.args.from) +
- "Receiver: " + Coin.balances.call(result.args.to));
- }
-}
-**/
-
-# Common paradigm for one contract to depend on another (e.g., a
-# contract that depends on current exchange rate provided by another)
-
-
-# ---
-
-
-# 6. BRANCHING AND LOOPS
-
-# All basic logic blocks from Python work - including if/elif/else, for,
-# while, break, continue, return - but no switch
-
-# Syntax same as Python, but no type conversion from non-boolean
-# to boolean (comparison operators must be used to get the boolean val)
-
-# REMEMBER: Vyper does not allow resursive calls or infinite loops
-
-
-# ---
-
-
-# 7. OBJECTS/CONTRACTS
-# REMEMBER: Vyper does not allow for inheritance or imports
-
-# A. CALLING EXTERNAL CONTRACTS
-# You must define an interface to an external contract in the current contract
-
-contract InfoFeed():
- def getInfo() -> uint256: constant
-
-info: uint256
-
-@public
-def __init__(_source: address):
- self.info = InfoFeed(_source).getInfo()
-
-
-# B. ERC20 BUILT-IN
-# Using the `ERC20` keyword implies that the contract at the address
-# follows the ERC20 token standard, allowing you to safely call
-# functions like `transfer()`, etc.
-
-tokenAddress: address(ERC20)
-
-@public
-def transferIt(_to: address, _amt: uint256(wei)):
- self.tokenAddress.transfer(_to, _amt)
-
-
-# C. FOLLOWING AN INTERFACE
-# Vyper is experimenting with using the following syntax at the top of
-# a `.vy` file to specify what interfaces are followed by the contract
-# This allows interfaces to be better organized, registered, and recognized
-
-import interfaces.some_interface as SomeInterface
-implements: SomeInterface
-# <rest of contract>
-
-
-# ---
-
-
-# 8. OTHER KEYWORDS
-
-# A. selfdestruct()
-# selfdestruct current contract, sending funds to address (often creator)
-selfdestruct(SOME_ADDRESS);
-
-# removes storage/code from current/future blocks
-# helps thin clients, but previous data persists in blockchain
-
-# Common pattern, lets owner end the contract and receive remaining funds
-@public
-def endItAll() {
- assert msg.sender == self.creator # Only let the contract creator do this
- selfdestruct(self.creator) # Makes contract inactive, returns funds
-
-# May want to deactivate contract manually, rather than selfdestruct
-# (ether sent to selfdestructed contract is lost)
-
-
-# B. sha3()
-# Encrypts strings and other data
-# Very important on the blockchain
-# Takes 1 argument, `concat()` can be called beforehand
-# All strings passed are concatenated before hash action
-sha3(concat("ab", "cd")) # returns bytes32
-
-
-# ---
-
-
-# 9. CONTRACT DESIGN NOTES
-
-# A. Obfuscation
-# All variables are publicly viewable on blockchain, so anything
-# that is private needs to be obfuscated (e.g., hashed w/secret)
-# Oftentimes, a "commit-reveal" scheme is employed
-
-# Step 1. Commit
-# Place a commitment by sending output of `sha3()`
-sha3("a secret"); # bytes32 commit
-sha3(concat("secret", "other secret", "salt")); # commit multiple things
-# The `sha3()` calculation should occur off-chain, only the bytes32
-# output should be inputted into some `commit()` function
-commits: map(address, bytes32)
-@public
-def commit(commitment: bytes32):
- self.commits[msg.sender] = commitment
-
-# Step 2. Reveal
-# Send your previously committed data so the contract can check
-# if your commitment was honest
-@public
-def reveal(_secret: string[100], _salt: string[100]) -> bool:
- return sha3(concat(_secret, _salt)) == self.commits[msg.sender]
-
-
-# B. Storage optimization
-# Writing to blockchain can be expensive, as data stored forever; encourages
-# smart ways to use memory (eventually, compilation will be better, but for now
-# benefits to planning data structures - and storing min amount in blockchain)
-
-# Cost can often be high for items like multidimensional arrays
-# (cost is for storing data - not declaring unfilled variables)
-
-
-# C. Data access in blockchain
-# Cannot restrict human or computer from reading contents of
-# transaction or transaction's state
-
-# While 'private' prevents other *contracts* from reading data
-# directly - any other party can still read data in blockchain
-
-# All data to start of time is stored in blockchain, so
-# anyone can observe all previous data and changes
-
-
-# D. Cron Job
-# Contracts must be manually called to handle time-based scheduling;
-# can create external code to regularly ping or provide incentives
-# (ether) for others to ping
-
-
-# E. Observer Pattern
-# An Observer Pattern lets you register as a subscriber and
-# register a function which is called by the oracle (note, the oracle
-# pays for this action to be run)
-# Some similarities to subscription in Pub/sub
-
-# This is an abstract contract, both client and server classes import,
-# the client should implement
-
-### **** START EXAMPLE **** ###
-
-contract SomeOracleCallback():
- def oracleCallback(_value: uint256, _time: timestamp, _info: bytes32): modifying
-
-MAX_SUBS: constant(uint256) = 100
-numSubs: public(uint256) # number of subscribers
-subs: map(uint256, address) # enumerates subscribers
-
-@public
-def addSub(_sub: address) -> uint256:
- """
- @notice Add subscriber
- @param _sub Address to add
- @return Id of newly added subscriber
- """
- self.subs[self.numSubs] = _sub
- self.numSubs += 1
- return self.numSubs - 1
-
-@private
-def notify(_value: uint256, _time: timestamp, _info: bytes32) -> bool:
- """
- @notice Notify all subscribers
- @dev Check `numSubs` first; Watch out for gas costs!
- @param _value whatever
- @param _time what have you
- @param _info what else
- @return True upon successful completion
- """
- j: uint256
- for i in range(MAX_SUBS):
- j = convert(i, uint256) # `i` is int128 by default
- if j == self.numSubs:
- return True
- SomeOracleCallback(self.subs[j]).oracleCallback(_value, _time, _info)
-
-@public
-def doSomething():
- """
- @notice Do something and notify subscribers
- """
- # ...something...
- whatever: uint256 = 6
- what_have_you: timestamp
- what_else: bytes32 = sha3("6")
- self.notify(whatever, what_have_you, what_else)
-
-# Now, your client contract can addSubscriber by importing SomeOracleCallback
-# and registering with Some Oracle
-
-### **** END EXAMPLE **** ###
-
-
-# ---
-
-
-# 10. SECURITY
-# Bugs can be disastrous in Ethereum contracts - and even popular patterns in
-# Vyper may be found to be antipatterns
-
-# See security links at the end of this doc
-
-
-# ---
-
-
-# 11. STYLE NOTES
-# Based on Python's PEP8 style guide
-# Full Style guide: http:#solidity.readthedocs.io/en/develop/style-guide.html
-
-# Quick summary:
-# 4 spaces for indentation
-# Two lines separate contract declarations (and other top level declarations)
-# Avoid extraneous spaces in parentheses
-# Can omit curly braces for one line statement (if, for, etc)
-# else should be placed on own line
-
-# Specific to Vyper:
-# arguments: snake_case
-# events, interfaces, structs: PascalCase
-# public functions: camelCase
-# private functions: _prefaceWithUnderscore
-
-
-# ---
-
-
-# 12. NATSPEC COMMENTS
-# used for documentation, commenting, and external UIs
-
-# Contract natspec - always above contract definition
-# @title Contract title
-# @author Author name
-
-# Function natspec
-# Should include in docstring of functions in typical Pythonic fashion
-# @notice Information about what function does; shown when function to execute
-# @dev Function documentation for developer
-
-# Function parameter/return value natspec
-# @param someParam Some description of what the param does
-# @return Description of the return value
-```
-
-## Additional resources
-- [Installation](https://vyper.readthedocs.io/en/latest/installing-vyper.html)
-- [Vyper Docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf)
-- [Vyper GitHub (under active dev)](https://github.com/ethereum/vyper)
-- [Tools and Resources](https://github.com/ethereum/vyper/wiki/Vyper-tools-and-resources)
-- [Online Compiler](https://vyper.online/)
-
-## Sample contracts
-- [Uniswap](https://github.com/Uniswap/contracts-vyper)
-- [Generalized Governance](https://github.com/kpeluso/gdg)
-- [Dynamic Arrays](https://github.com/kpeluso/vyper-dynamic-array)
-
-## Security
-Vyper is secure by design, but it may be helpful to understand what Vyper is
-protecting you from.
-- [Thinking About Smart Contract Security](https:#blog.ethereum.org/2016/06/19/thinking-smart-contract-security/)
-- [Smart Contract Security](https:#blog.ethereum.org/2016/06/10/smart-contract-security/)
-- [Hacking Distributed Blog](http:#hackingdistributed.com/)
-
-## Style
-- [Vyper Style Guide WIP](https://github.com/ethereum/vyper/issues/905)
- - Heavily derived from [Solidity's style guide](http:#solidity.readthedocs.io/en/latest/style-guide.html) ...
- - ... which, in turn, is heavily derived from Python's [PEP 8](https:#www.python.org/dev/peps/pep-0008/) style guide.
-
-## Editors
-- [Vyper for VS Code (alpha)](https://github.com/p-/vscode-vyper)
-
-## Future To Dos
-- Update to current Vyper release
-- List of common design patterns
-
-*Feel free to send a pull request with any edits - or email* `pelusoken -/at-/ gmail`
-