Note: Slides can be autogenerated from this .md
markdown file using tools like marp, remarkjs, etc.
Freelance full-stack Eth dev.
Building Tasit project.
I help with organizing the Chicago Ethereum Meetup.
The markdown file with all of this info we’ll be talking about is available at:
Alternatively, you can get here directly via GitHub:
Feel free to interrupt me at any time. Freeform / real-time questions work best for me.
Or if you’re feeling shy, we can crowdsource questions online. Go to sli.do and enter the event code #8th-light-ethereum
. I’ll stop to check for the most upvoted questions at some point during the workshop.
Here is the direct link to the sli.do with our questions, etc. from during the talk: https://app.sli.do/event/qbv9lvdr/live/questions
In order for this exploration to be tangibly meaningful, let’s set up wallets first.
While there are lots of choices for wallets, it will be the simplest if you all use MetaMask for today.
I’ll send you all testnet ETH shortly using the testnet version of the Gnosis Safe (a different Ethereum wallet that has cool features like account recovery).
There are lots of other great alternatives that we won’t have time to try out today including: Argent, Coinbase Wallet, Status, and Trust.
{ Walk around scanning QR codes to send ETH on the Rinkeby testnet }
{ Show a tour of Etherscan }
Here are some alternatives to Etherscan:
Etherscan
Visual tools by Alethio:
Note: Programmatic tools covered later in the “reading data” section of this talk
Why does crypto / blockchain tech matter?
Why cover this through the lens of Ethereum?
Developer network effect
Defaults matter
Zero platform risk -> the great unbundling of front end and back end (and of individual front end features). Users get “right to exit” meaning that they can elect to use alternative clients without losing all of their data and the network effect of the platform, and the tech tycoons of the future can’t prevent them from doing so.
The wallets you set up earlier are a prerequisite for using these dapps.
(Note: Hopefully that won’t be the case in the future.)
Note: You should be logged into the MetaMask browser extension and load this page on a PC in order for it to show up properly.
{ Set up an Aragon DAO for the group }
Here’s the Aragon DAO we created during the workshop: https://rinkeby.aragon.org/#/somethingssilly/0xc115960ace21e4d87b951ef11fdfdb38e170d19c/
Note that there are two s’s at the beginning of silly - a typo
Humanity DAO (caveat that this is kind of a DAO and an identity solution too)
Exchanges
Lending
Credit
Insurance
Prediction markets Guesser and Sight by Gnosis
{ Try Uniswap }
{ Optional: Purchase a digital collectible and exchange it with others. }
Cent
Peepeth
{ Talk a bit about how gas is used on Ethereum }
Here’s an example project set up on studio.ethereum.org
The Truffle framework for developing smart contracts
Or Buidler (task runner), ethers, Waffle (test runner), and TypeChain (typings for smart contracts)
ethers
Signers and providers are different features
Provider might be Infura, Alchemy, Etherscan, your own local node
Has a CLI
import { ethers } from "@nomiclabs/buidler";
import chai from "chai";
import { deployContract, getWallets, solidity } from "ethereum-waffle";
import CounterAbi from "../build/Counter.json";
import { Counter } from "../types/Counter";
chai.use(solidity);
const { expect } = chai;
describe("Counter", () => {
const provider = ethers.provider;
const [wallet] = getWallets(provider);
// use contract type
let counter: Counter;
beforeEach(async () => {
// cast as type
counter = await deployContract(wallet, CounterAbi) as Counter;
// function name is available as part of types
const initialCount = await counter.getCount();
expect(initialCount).to.eq(0);
expect(counter.address).to.properAddress;
});
it("should count up", async () => {
await counter.countUp();
let count = await counter.getCount();
expect(count).to.eq(1);
await counter.countUp();
count = await counter.getCount();
expect(count).to.eq(2);
});
it("should count down", async () => {
await counter.countDown();
const count = await counter.getCount();
expect(count).to.eq(0);
});
});
{ Mention potential CLI usage with ENS }
import { Web3ReactProvider } from "@web3-react/core";
import { ethers } from "ethers";
function getLibrary(provider) {
const library = new ethers.providers.Web3Provider(provider);
library.pollingInterval = 10000;
return library;
}
ReactDOM.render(
<Web3ReactProvider getLibrary={getLibrary}>
<App />
</Web3ReactProvider>,
document.getElementById("root")
);
import { InjectedConnector } from "@web3-react/injected-connector";
export const injected = new InjectedConnector({
supportedChainIds: [1]
});
import { injected } from "../connectors";
import { useState, useEffect } from "react";
import { useWeb3React } from "@web3-react/core";
export default function WalletComponent() {
const { activate, active } = useWeb3React();
const [tried, setTried] = useState(false);
const tryActivation = async connector => {
try {
await activate(connector, undefined, true);
} catch (e) {
setTried(true);
}
};
return (
<OptionGrid>
<Option
onClick={() => {
tryActivation(injected);
}}
active={injected === connector}
color="#E8831D"
header="MetaMask"
icon={require("../../assets/images/metamask.png")}
/>
</OptionGrid>
);
}
There are some tools out there for this as well
Thanks! Any questions?
@paulcowgill on Twitter