Thursday, September 30, 2021
Tuesday, September 28, 2021
Ethereum Programming 14 tip author
tipper send 1 ether to author
//src/contracts/Decentragram.solpragma solidity ^0.5.0;
contract Decentragram {
  // Code goes here...
  string public name = "Decentragram";
  uint public imageCount = 0;
  mapping(uint => Image) public images;
  struct Image{
    uint id;
    string hash;
    string description;
    uint tipAmount;
    address payable author;
  }
  event ImageCreated(
    uint id,
    string hash,
    string description,
    uint tipAmount,
    address payable author
  );
  event ImageTipped(
    uint id,
    string hash,
    string description,
    uint tipAmount,
    address payable author
  );
  function uploadImage(string memory _imgHash, string memory _description) public {
    require(bytes(_imgHash).length > 0);
    require(bytes(_description).length > 0);
    require(msg.sender != address(0x0));
    imageCount++;
    images[imageCount] = Image(imageCount, _imgHash, _description, 0, msg.sender);
    emit ImageCreated(imageCount, _imgHash, _description, 0, msg.sender);
  }
  function tipImageOwner(uint _id) public payable{
    require(_id > 0 && _id <= imageCount);
    Image memory _image = images[_id];
    address payable _author = _image.author;
    address(_author).transfer(msg.value);
    _image.tipAmount = _image.tipAmount + msg.value;
    images[_id] = _image;
    emit ImageTipped(_id, _image.hash, _image.description, _image.tipAmount, _author);
  }
}
-------------------------
//test/test.js
const { assert } = require('chai')
const Decentragram = artifacts.require('./Decentragram.sol')
require('chai')
  .use(require('chai-as-promised'))
  .should()
contract('Decentragram', ([deployer, author, tipper]) => {
  let decentragram
  before(async () => {
    decentragram = await Decentragram.deployed()
  })
  describe('deployment', async () => {
    it('deploys successfully', async () => {
      const address = await decentragram.address
      assert.notEqual(address, 0x0)
      assert.notEqual(address, '')
      assert.notEqual(address, null)
      assert.notEqual(address, undefined)
    })
    it('has a name', async () => {
      const name = await decentragram.name()
      assert.equal(name, 'Decentragram')
    })
  })
  describe('images', async () => {
    let result, imageCount
    const hash = 'abc123'
    before(async () => {
      result = await decentragram.uploadImage(hash, 'Image description', { from: author })
      imageCount = await decentragram.imageCount()
    })
    it('create images', async () => {
      //console.log(result)
      //console.log(result.logs[0].args)
      const event = result.logs[0].args
      assert.equal(event.id.toNumber(), imageCount.toNumber(), 'id is correct')
      assert.equal(event.hash, hash, 'Hash is correct')
      assert.equal(event.description, 'Image description', 'description is correct')
      assert.equal(event.tipAmount, '0', 'tip amount is correct')
      assert.equal(event.author, author, 'author is correct')
      await decentragram.uploadImage('', 'Image description', { from: author }).should.be.rejected;
      await decentragram.uploadImage('Image hash', '', { from: author }).should.be.rejected;
      await decentragram.uploadImage('Image hash', 'Image description', { from: '' }).should.be.rejected;
    })
    it('lists images', async () => {
      const image = await decentragram.images(imageCount)
      assert.equal(image.id.toNumber(), imageCount.toNumber(), 'id is correct')
      assert.equal(image.hash, hash, 'Hash is correct')
      assert.equal(image.description, 'Image description', 'description is correct')
      assert.equal(image.tipAmount, '0', 'tip amount is correct')
      assert.equal(image.author, author, 'author is correct')
    })
    it('allows users to tip images', async () => {
      // Track the author balance before purchase
      let oldAuthorBalance
      oldAuthorBalance = await web3.eth.getBalance(author)
      oldAuthorBalance = new web3.utils.BN(oldAuthorBalance)
       //console.log(imageCount.toNumber(), author, tipper)
      result = await decentragram.tipImageOwner(imageCount, { from: tipper, value: web3.utils.toWei('1', 'Ether') })
      // SUCCESS
      const event = result.logs[0].args
      assert.equal(event.id.toNumber(), imageCount.toNumber(), 'id is correct')
      assert.equal(event.hash, hash, 'Hash is correct')
      assert.equal(event.description, 'Image description', 'description is correct')
      assert.equal(event.tipAmount, '1000000000000000000', 'tip amount is correct')
      assert.equal(event.author, author, 'author is correct')
      // Check that author received funds
      let newAuthorBalance
      newAuthorBalance = await web3.eth.getBalance(author)
      newAuthorBalance = new web3.utils.BN(newAuthorBalance)
      let tipImageOwner
      tipImageOwner = web3.utils.toWei('1', 'Ether')
      tipImageOwner = new web3.utils.BN(tipImageOwner)
      const expectedBalance = oldAuthorBalance.add(tipImageOwner)
      assert.equal(newAuthorBalance.toString(), expectedBalance.toString())
      // FAILURE: Tries to tip a image that does not exist
      await decentragram.tipImageOwner(99, { from: tipper, value: web3.utils.toWei('1', 'Ether') }).should.be.rejected;
    })
  })
})
------------------
//logs
Contract: Decentragram
    deployment
      √ deploys successfully
      √ has a name (136ms)
    images
      √ create images (1092ms)
      √ lists images (104ms)
      √ allows users to tip images (602ms)
  5 passing (3s)
reference:
Sunday, September 26, 2021
Ethereum Programming 13 upload image 2
//cmd -console.log(result)
  
PS C:\Users\zchen\Programming\decentragram-starter-code> truffle test
Using network 'development'.
Compiling your contracts...
===========================
> Compiling .\src\contracts\Decentragram.sol
> Compiling .\src\contracts\Decentragram.sol
> Compiling .\src\contracts\Migrations.sol
> Artifacts written to C:\Users\zchen\AppData\Local\Temp\test--14908-izXoOAEen8OE
> Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang
  Contract: Decentragram
    deployment
      √ deploys successfully
      √ has a name (190ms)
    images
{
  tx: '0xdeaed902492c5399b6b4dd719a5de01351f560ec03c5776dd269e6754f8de3b4',
  receipt: {
    transactionHash: '0xdeaed902492c5399b6b4dd719a5de01351f560ec03c5776dd269e6754f8de3b4',
    transactionIndex: 0,
    blockHash: '0xad50fed8fbaf6b2b7cbe3d7533837f290a671ace2211c34f7378c9fb13389425',
    blockNumber: 45,
    from: '0x2ebfb7af01da3f8e73d2938a928289f2ef633c4e',
    to: '0x6b70d1407fcffa192f9b18658abe485f4db6dac2',
    gasUsed: 134507,
    cumulativeGasUsed: 134507,
    contractAddress: null,
    logs: [ [Object] ],
    status: true,
    logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001000000000000000000000000000000000008800000000000000000000000000000040000',
    rawLogs: [ [Object] ]
  },
  logs: [
    {
      logIndex: 0,
      transactionIndex: 0,
      transactionHash: '0xdeaed902492c5399b6b4dd719a5de01351f560ec03c5776dd269e6754f8de3b4',
      blockHash: '0xad50fed8fbaf6b2b7cbe3d7533837f290a671ace2211c34f7378c9fb13389425',
      blockNumber: 45,
      address: '0x6B70d1407fcfFa192F9b18658ABE485f4Db6Dac2',
      type: 'mined',
      id: 'log_2d9f031a',
      event: 'ImageCreated',
      args: [Result]
    }
  ]
}
      √ create images
  3 passing (782ms)
  ----------------------------
//cmd - console.log(result.logs[0].args)
  PS C:\Users\zchen\Programming\decentragram-starter-code> truffle test
Using network 'development'.
Compiling your contracts...
===========================
> Compiling .\src\contracts\Decentragram.sol
> Compiling .\src\contracts\Decentragram.sol
> Compiling .\src\contracts\Migrations.sol
> Artifacts written to C:\Users\zchen\AppData\Local\Temp\test--14816-pzQlEL64rrKB
> Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang
  Contract: Decentragram
    deployment
      √ deploys successfully
      √ has a name (203ms)
    images
Result {
  '0': BN {
    negative: 0,
    words: [ 1, <1 empty item> ],
    length: 1,
    red: null
  },
  '1': 'abc123',
  '2': 'Image description',
  '3': BN {
    negative: 0,
    words: [ 0, <1 empty item> ],
    length: 1,
    red: null
  },
  '4': '0x2EbFB7Af01Da3F8E73D2938A928289F2ef633c4E',
  __length__: 5,
  id: BN {
    negative: 0,
    words: [ 1, <1 empty item> ],
    length: 1,
    red: null
  },
  hash: 'abc123',
  description: 'Image description',
  tipAmount: BN {
    negative: 0,
    words: [ 0, <1 empty item> ],
    length: 1,
    red: null
  },
  author: '0x2EbFB7Af01Da3F8E73D2938A928289F2ef633c4E'
}
      √ create images
  3 passing (757ms)
---------------------------
//test/test.js
const { assert } = require('chai')
const Decentragram = artifacts.require('./Decentragram.sol')
require('chai')
  .use(require('chai-as-promised'))
  .should()
contract('Decentragram', ([deployer, author, tipper]) => {
  let decentragram
  before(async () => {
    decentragram = await Decentragram.deployed()
  })
  describe('deployment', async () => {
    it('deploys successfully', async () => {
      const address = await decentragram.address
      assert.notEqual(address, 0x0)
      assert.notEqual(address, '')
      assert.notEqual(address, null)
      assert.notEqual(address, undefined)
    })
    it('has a name', async () => {
      const name = await decentragram.name()
      assert.equal(name, 'Decentragram')
    })
  })
  describe('images', async () => {
    let result, imageCount
    const hash = 'abc123'
    before(async () => {
      result = await decentragram.uploadImage(hash, 'Image description', { from: author })
      imageCount = await decentragram.imageCount()
    })
    it('create images', async () => {
      //console.log(result)
      //console.log(result.logs[0].args)
      const event = result.logs[0].args
      assert.equal(event.id.toNumber(), imageCount.toNumber(), 'id is correct')
      assert.equal(event.hash, hash, 'Hash is correct')
      assert.equal(event.description, 'Image description', 'description is correct')
      assert.equal(event.tipAmount, '0', 'tip amount is correct')
      assert.equal(event.author, author, 'author is correct')
    })
  })
})
------------------------
//src/contracts/Decentragram.sol
pragma solidity ^0.5.0;
contract Decentragram {
  // Code goes here...
  string public name = "Decentragram";
  uint public imageCount = 0;
  mapping(uint => Image) public images;
  struct Image{
    uint id;
    string hash;
    string description;
    uint tipAmount;
    address payable author;
  }
  event ImageCreated(
    uint id,
    string hash,
    string description,
    uint tipAmount,
    address payable author
  );
  function uploadImage(string memory _imgHash, string memory _description) public {
    imageCount++;
    images[imageCount] = Image(imageCount, _imgHash, _description, 0, msg.sender);
    emit ImageCreated(imageCount, _imgHash, _description, 0, msg.sender);
  }
}
reference:
Ethereum Programming 12 upload image 1
//cmd
truffle test
Contract: Decentragram
    deployment
      √ deploys successfully
      √ has a name (220ms)
    images
Result {
  '0': BN {
    negative: 0,
    words: [ 1, <1 empty item> ],
    length: 1,
    red: null
  },
  '1': 'abc123',
  '2': 'hello',
  '3': BN {
    negative: 0,
    words: [ 0, <1 empty item> ],
    length: 1,
    red: null
  },
  '4': '0x0000000000000000000000000000000000000000',
  id: BN {
    negative: 0,
    words: [ 1, <1 empty item> ],
    length: 1,
    red: null
  },
  hash: 'abc123',
  description: 'hello',
  tipAmount: BN {
    negative: 0,
    words: [ 0, <1 empty item> ],
    length: 1,
    red: null
  },
  author: '0x0000000000000000000000000000000000000000'
}
      √ create images (583ms)
-------------------------
//test/test.js
const Decentragram = artifacts.require('./Decentragram.sol')
require('chai')
  .use(require('chai-as-promised'))
  .should()
contract('Decentragram', ([deployer, author, tipper]) => {
  let decentragram
  before(async () => {
    decentragram = await Decentragram.deployed()
  })
  describe('deployment', async () => {
    it('deploys successfully', async () => {
      const address = await decentragram.address
      assert.notEqual(address, 0x0)
      assert.notEqual(address, '')
      assert.notEqual(address, null)
      assert.notEqual(address, undefined)
    })
    it('has a name', async () => {
      const name = await decentragram.name()
      assert.equal(name, 'Decentragram')
    })
  })
  describe('images', async () => {
    let result
    it('create images', async () => {
      result = await decentragram.uploadImage()
      let image = await decentragram.images(1)
      console.log(image)
    })
  })
})
--------------------------------
//src/contracts/Decentragram.sol
pragma solidity ^0.5.0;
contract Decentragram {
  // Code goes here...
  string public name = "Decentragram";
  mapping(uint => Image) public images;
  struct Image{
    uint id;
    string hash;
    string description;
    uint tipAmount;
    address payable author;
  }
  function uploadImage() public {
    images[1] = Image(1, 'abc123', 'hello', 0, address(0x0));
  }
}
reference:
Saturday, September 25, 2021
Ethereum Programming 11 decentragram 1
//cmd
truffle migrate --reset
truffle test
Contract: Decentragram
    deployment
      √ deploys successfully
      √ has a name (203ms)
  2 passing (291ms)
--------------------------------
//migrations/2_deploy_contracts.js
const Decentragram = artifacts.require("Decentragram");
module.exports = function (deployer) {
  deployer.deploy(Decentragram);
};
---------------------------
//src/contracs/Decentragram.sol
pragma solidity ^0.5.0;
contract Decentragram {
  // Code goes here...
  string public name = "Decentragram";
}
----------------------
//test/test.js
const Decentragram = artifacts.require('./Decentragram.sol')
require('chai')
  .use(require('chai-as-promised'))
  .should()
contract('Decentragram', ([deployer, author, tipper]) => {
  let decentragram
  before(async () => {
    decentragram = await Decentragram.deployed()
  })
  describe('deployment', async () => {
    it('deploys successfully', async () => {
      const address = await decentragram.address
      assert.notEqual(address, 0x0)
      assert.notEqual(address, '')
      assert.notEqual(address, null)
      assert.notEqual(address, undefined)
    })
    it('has a name', async () => {
      const name = await decentragram.name()
      assert.equal(name, 'Decentragram')
    })
  })
})
reference:
Friday, September 24, 2021
Ethereum Programming 10 generate interest
investor deposit 100mDai and earned 100Dapp
investor earned another 100Dapp
investor withdraw principle 100mDai, interest 200Dapp left in token farm
//cmdtruffle exec scripts/issue-token.js
------------------------
//scripts/issue-token.js
const TokenFarm = artifacts.require('TokenFarm')
module.exports = async function (callback) {
    let tokenFarm = await TokenFarm.deployed()
    await tokenFarm.issueTokens()
    console.log("Tokens issued!")
    callback()
}
------------------------
//src/contracts/TokenFarm.sol
pragma solidity ^0.5.0;
import "./DappToken.sol";
import "./DaiToken.sol";
contract TokenFarm{
    string public name = "Dapp Token Farm";
    DappToken public dappToken;
    DaiToken public daiToken;
    address public owner;
    address[] public stakers;
    mapping(address => uint) public stakingBalance;
    mapping(address => bool) public hasStaked;
    mapping(address => bool) public isStaking;
    constructor(DappToken _dappToken, DaiToken _daiToken) public{
        dappToken = _dappToken;
        daiToken = _daiToken;
        owner = msg.sender;
    }
    function stakeTokens(uint _amount) public{
        require(_amount > 0, "amount greater than 0");
        daiToken.transferFrom(msg.sender, address(this), _amount);
        stakingBalance[msg.sender] = stakingBalance[msg.sender] + _amount;
        if(!hasStaked[msg.sender]){
            stakers.push(msg.sender);
        }
        isStaking[msg.sender] = true;
        hasStaked[msg.sender] = true;
    }
    function unstakeTokens() public {
        uint balance = stakingBalance[msg.sender];
        require(balance > 0, "staking balance greater than 0");
        daiToken.transfer(msg.sender, balance);
        stakingBalance[msg.sender] = 0;
        isStaking[msg.sender] = false;
    }
    function issueTokens() public {
        require(msg.sender == owner, "caller must be the owner");
        for (uint i=0; i<stakers.length; i++){
            uint balance = stakingBalance[stakers[i]];
            if(balance > 0){
                dappToken.transfer(stakers[i], balance);
            }
        }
    }
}
reference:
Wednesday, September 22, 2021
Tuesday, September 21, 2021
Ethereum Programming 9 react UI
investor has 100mDai
deposit 30mDai
token farm owner approves deposit
30mDai deposited
investor agrees to pay gas fee
investor has 70mDai in his account, and 30mDai in token farm.
investor withdraw from token farm
investor has 100mDai in his account
//src/app.js
import React, { Component } from 'react'
import Web3 from 'web3'
import DaiToken from '../abis/DaiToken.json'
import DappToken from '../abis/DappToken.json'
import TokenFarm from '../abis/TokenFarm.json'
import Navbar from './Navbar'
import Main from './Main'
import './App.css'
class App extends Component {
  async componentWillMount() {
    await this.loadWeb3()
    await this.loadBlockchainData()
  }
  async loadBlockchainData() {
    const web3 = window.web3
    const accounts = await web3.eth.getAccounts()
    console.log(accounts)
    this.setState({ account: accounts[0] })
    const networkId = await web3.eth.net.getId()
    // Load DaiToken
    const daiTokenData = DaiToken.networks[networkId]
    if (daiTokenData) {
      const daiToken = new web3.eth.Contract(DaiToken.abi, daiTokenData.address)
      this.setState({ daiToken })
      let daiTokenBalance = await daiToken.methods.balanceOf(this.state.account).call()
      this.setState({ daiTokenBalance: daiTokenBalance.toString() })
    } else {
      window.alert('DaiToken contract not deployed to detected network.')
    }
    // Load DappToken
    const dappTokenData = DappToken.networks[networkId]
    if (dappTokenData) {
      const dappToken = new web3.eth.Contract(DappToken.abi, dappTokenData.address)
      this.setState({ dappToken })
      let dappTokenBalance = await dappToken.methods.balanceOf(this.state.account).call()
      this.setState({ dappTokenBalance: dappTokenBalance.toString() })
    } else {
      window.alert('DappToken contract not deployed to detected network.')
    }
    // Load TokenFarm
    const tokenFarmData = TokenFarm.networks[networkId]
    if (tokenFarmData) {
      const tokenFarm = new web3.eth.Contract(TokenFarm.abi, tokenFarmData.address)
      this.setState({ tokenFarm })
      let stakingBalance = await tokenFarm.methods.stakingBalance(this.state.account).call()
      this.setState({ stakingBalance: stakingBalance.toString() })
    } else {
      window.alert('TokenFarm contract not deployed to detected network.')
    }
    this.setState({ loading: false })
  }
  async loadWeb3() {
    if (window.ethereum) {
      window.web3 = new Web3(window.ethereum)
      await window.ethereum.enable()
    }
    else if (window.web3) {
      window.web3 = new Web3(window.web3.currentProvider)
    }
    else {
      window.alert('Non-Ethereum browser detected. You should consider trying MetaMask!')
    }
  }
  stakeTokens = (amount) => {
    this.setState({ loading: true })
    this.state.daiToken.methods.approve(this.state.tokenFarm._address, amount).send({ from: this.state.account }).on('transactionHash', (hash) => {
      this.state.tokenFarm.methods.stakeTokens(amount).send({ from: this.state.account }).on('transactionHash', (hash) => {
        this.setState({ loading: false })
      })
    })
  }
  unstakeTokens = (amount) => {
    this.setState({ loading: true })
    this.state.tokenFarm.methods.unstakeTokens().send({ from: this.state.account }).on('transactionHash', (hash) => {
      this.setState({ loading: false })
    })
  }
  constructor(props) {
    super(props)
    this.state = {
      account: '0x0',
      daiToken: {},
      dappToken: {},
      tokenFarm: {},
      daiTokenBalance: '0',
      dappTokenBalance: '0',
      stakingBalance: '0',
      loading: true
    }
  }
  render() {
    let content
    if (this.state.loading) {
      content = <p id="loader" className="text-center">Loading...</p>
    } else {
      content = <Main
        daiTokenBalance={this.state.daiTokenBalance}
        dappTokenBalance={this.state.dappTokenBalance}
        stakingBalance={this.state.stakingBalance}
        stakeTokens={this.stakeTokens}
        unstakeTokens={this.unstakeTokens}
      />
    }
    return (
      <div>
        <Navbar account={this.state.account} />
        <div className="container-fluid mt-5">
          <div className="row">
            <main role="main" className="col-lg-12 ml-auto mr-auto" style={{ maxWidth: '600px' }}>
              <div className="content mr-auto ml-auto">
                <a
                  href="http://www.dappuniversity.com/bootcamp"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                </a>
                {content}
              </div>
            </main>
          </div>
        </div>
      </div>
    );
  }
}
export default App;
reference:
Monday, September 20, 2021
Ethereum Programming 8 metamask
//download chrome metamask extension
//open metamask
copy secret words from ganache server
metamask import existing wallet
paste secret words from ganache server
verify metamask account 1 address is the same as ganache account 1
select custom PRC
paste ganach server url
import account
paste private key of 2nd address on ganache as investor account
account is setup
reference:
Ethereum Programming 7 scripts 1
//cmd
truffle migrate --resettruffle exec scripts/issue-token.js
//logs
Tokens issued!
------------------------
//scripts/issue-token.js
const TokenFarm = artifacts.require('TokenFarm')
module.exports = async function (callback) {
    let tokenFarm = await TokenFarm.deployed()
    await tokenFarm.issueTokens()
    console.log("Tokens issued!")
    callback()
}
reference:
Sunday, September 19, 2021
Ethereum Programming 6 withdraw, issue interest
//contracts/TokenFarm.sol
    
pragma solidity ^0.5.0;
import "./DappToken.sol";
import "./DaiToken.sol";
contract TokenFarm{
    string public name = "Dapp Token Farm";
    DappToken public dappToken;
    DaiToken public daiToken;
    address public owner;
    address[] public stakers;
    mapping(address => uint) public stakingBalance;
    mapping(address => bool) public hasStaked;
    mapping(address => bool) public isStaking;
    constructor(DappToken _dappToken, DaiToken _daiToken) public{
        dappToken = _dappToken;
        daiToken = _daiToken;
        owner = msg.sender;
    }
    function stakeTokens(uint _amount) public{
        require(_amount > 0, "amount greater than 0");
        daiToken.transferFrom(msg.sender, address(this), _amount);
        stakingBalance[msg.sender] = stakingBalance[msg.sender] + _amount;
        if(!hasStaked[msg.sender]){
            stakers.push(msg.sender);
        }
        isStaking[msg.sender] = true;
        hasStaked[msg.sender] = true;
    }
    function unstakeTokens() public {
        uint balance = stakingBalance[msg.sender];
        require(balance > 0, "staking balance greater than 0");
        daiToken.transfer(msg.sender, balance);
        stakingBalance[msg.sender] = 0;
        isStaking[msg.sender] = false;
    }
    function issueTokens() public {
        require(msg.sender == owner, "caller must be the owner");
        for (uint i=0; i<stakers.length; i++){
            uint balance = stakingBalance[stakers[i]];
            if(balance > 0){
                dappToken.transfer(stakers[i], balance);
            }
        }
    }
}
--------------------------------
//test/TokenFarm.test.js
const { assert } = require('chai')
const DappToken = artifacts.require('DappToken')
const DaiToken = artifacts.require('DaiToken')
const TokenFarm = artifacts.require('TokenFarm')
require('chai')
    .use(require('chai-as-promised'))
    .should()
function tokens(n) {
    return web3.utils.toWei(n, 'Ether')
}
contract('TokenFarm', ([owner, investor]) => {
    let daiToken, dappToken, tokenFarm
    before(async () => {
        daiToken = await DaiToken.new()
        dappToken = await DappToken.new()
        tokenFarm = await TokenFarm.new(dappToken.address, daiToken.address)
        await dappToken.transfer(tokenFarm.address, tokens('1000000'))
        await daiToken.transfer(investor, tokens('100'), { from: owner })
    })
    describe('Mock Dai deployment', async () => {
        it('has a name', async () => {
            const name = await daiToken.name()
            assert.equal(name, 'Mock DAI Token')
        })
    })
    describe('Dapp Token deployment', async () => {
        it('has a name', async () => {
            const name = await dappToken.name()
            assert.equal(name, 'DApp Token')
        })
    })
    describe('Token Farm deployment', async () => {
        it('has a name', async () => {
            const name = await tokenFarm.name()
            assert.equal(name, 'Dapp Token Farm')
        })
        it('contract has tokens', async () => {
            let balance = await dappToken.balanceOf(tokenFarm.address)
            assert.equal(balance.toString(), tokens('1000000'))
        })
    })
    describe('Farming tokens', async () => {
        it('rewards investors for staking mDai tokens', async () => {
            let result
            result = await daiToken.balanceOf(investor)
            assert.equal(result.toString(), tokens('100', 'investor Mock Dai wallet balance correct before staking'))
            await daiToken.approve(tokenFarm.address, tokens('100'), { from: investor })
            await tokenFarm.stakeTokens(tokens('100'), { from: investor })
            result = await daiToken.balanceOf(investor)
            assert.equal(result.toString(), tokens('0'), 'investor Mock DAI wallet balance correct after staking')
            result = await tokenFarm.stakingBalance(investor)
            assert.equal(result.toString(), tokens('100'), 'investor staking balance correct after staking')
            result = await tokenFarm.isStaking(investor)
            assert.equal(result.toString(), 'true', 'investor staking status correct after staking')
            await tokenFarm.issueTokens({ from: owner })
            result = await dappToken.balanceOf(investor)
            assert.equal(result.toString(), tokens('100'), 'investor DApp Token wallet ballance correct after staking')
            await tokenFarm.issueTokens({ from: investor }).should.be.rejected;
            await tokenFarm.unstakeTokens({ from: investor })
            result = await daiToken.balanceOf(investor)
            assert.equal(result.toString(), tokens('100'), 'investor Mock DAI wallet balance correct after unstaking')
            result = await daiToken.balanceOf(tokenFarm.address)
            assert.equal(result.toString(), tokens('0'), 'Token Farm Mock DAI wallet balance correct after unstaking')
            result = await tokenFarm.stakingBalance(investor)
            assert.equal(result.toString(), tokens('0'), 'investor staking balance correct after unstaking')
            result = await tokenFarm.isStaking(investor)
            assert.equal(result.toString(), 'false', 'investor staking status correct after unstaking')
        })
    })
})
--------------------------------------
//logs
Contract: TokenFarm
    Mock Dai deployment
      √ has a name (243ms)
    Dapp Token deployment
      √ has a name (68ms)
    Token Farm deployment
      √ has a name (91ms)
      √ contract has tokens (101ms)
    Farming tokens
      √ rewards investors for staking mDai tokens (3323ms)
  5 passing (6s)
reference:
Saturday, September 18, 2021
Ethereum Programming 5 deposit
//contracts/TokenFarm.sol
    
pragma solidity ^0.5.0;
import "./DappToken.sol";
import "./DaiToken.sol";
contract TokenFarm{
    string public name = "Dapp Token Farm";
    DappToken public dappToken;
    DaiToken public daiToken;
    address[] public stakers;
    mapping(address => uint) public stakingBalance;
    mapping(address => bool) public hasStaked;
    mapping(address => bool) public isStaking;
    constructor(DappToken _dappToken, DaiToken _daiToken) public{
        dappToken = _dappToken;
        daiToken = _daiToken;
    }
    function stakeTokens(uint _amount) public{
        daiToken.transferFrom(msg.sender, address(this), _amount);
        stakingBalance[msg.sender] = stakingBalance[msg.sender] + _amount;
        if(!hasStaked[msg.sender]){
            stakers.push(msg.sender);
        }
        isStaking[msg.sender] = true;
        hasStaked[msg.sender] = true;
    }
}
--------------------------------
//test/TokenFarm.test.js
const { assert } = require('chai')
const DappToken = artifacts.require('DappToken')
const DaiToken = artifacts.require('DaiToken')
const TokenFarm = artifacts.require('TokenFarm')
require('chai')
    .use(require('chai-as-promised'))
    .should()
function tokens(n) {
    return web3.utils.toWei(n, 'Ether')
}
contract('TokenFarm', ([owner, investor]) => {
    let daiToken, dappToken, tokenFarm
    before(async () => {
        daiToken = await DaiToken.new()
        dappToken = await DappToken.new()
        tokenFarm = await TokenFarm.new(dappToken.address, daiToken.address)
        await dappToken.transfer(tokenFarm.address, tokens('1000000'))
        await daiToken.transfer(investor, tokens('100'), { from: owner })
    })
    describe('Mock Dai deployment', async () => {
        it('has a name', async () => {
            const name = await daiToken.name()
            assert.equal(name, 'Mock DAI Token')
        })
    })
    describe('Dapp Token deployment', async () => {
        it('has a name', async () => {
            const name = await dappToken.name()
            assert.equal(name, 'DApp Token')
        })
    })
    describe('Token Farm deployment', async () => {
        it('has a name', async () => {
            const name = await tokenFarm.name()
            assert.equal(name, 'Dapp Token Farm')
        })
        it('contract has tokens', async () => {
            let balance = await dappToken.balanceOf(tokenFarm.address)
            assert.equal(balance.toString(), tokens('1000000'))
        })
    })
    describe('Farming tokens', async () => {
        it('rewards investors for staking mDai tokens', async () => {
            let result
            result = await daiToken.balanceOf(investor)
            assert.equal(result.toString(), tokens('100', 'investor Mock Dai wallet balance correct before staking'))
            await daiToken.approve(tokenFarm.address, tokens('100'), { from: investor })
            await tokenFarm.stakeTokens(tokens('100'), { from: investor })
            result = await daiToken.balanceOf(investor)
            assert.equal(result.toString(), tokens('0'), 'investor Mock DAI wallet balance correct after staking')
            result = await tokenFarm.stakingBalance(investor)
            assert.equal(result.toString(), tokens('100'), 'investor staking balance correct after staking')
            result = await tokenFarm.isStaking(investor)
            assert.equal(result.toString(), 'true', 'investor staking status correct after staking')
        })
    })
})
-----------------------
//logs
Contract: TokenFarm
    Mock Dai deployment
      √ has a name (188ms)
    Dapp Token deployment
      √ has a name (126ms)
    Token Farm deployment
      √ has a name (95ms)
      √ contract has tokens (155ms)
    Farming tokens
      √ rewards investors for staking mDai tokens (1107ms)
  5 passing (3s)
reference;
Friday, September 17, 2021
Ethereum Programming 4 testing verify token name and balance
 //TokenFarm.test.js
const { assert } = require('chai')
const DappToken = artifacts.require('DappToken')
const DaiToken = artifacts.require('DaiToken')
const TokenFarm = artifacts.require('TokenFarm')
require('chai')
    .use(require('chai-as-promised'))
    .should()
function tokens(n) {
    return web3.utils.toWei(n, 'Ether')
}
contract('TokenFarm', ([owner, investor]) => {
    let daiToken, dappToken, tokenFarm
    before(async () => {
        daiToken = await DaiToken.new()
        dappToken = await DappToken.new()
        tokenFarm = await TokenFarm.new(dappToken.address, daiToken.address)
        await dappToken.transfer(tokenFarm.address, tokens('1000000'))
        await daiToken.transfer(investor, tokens('100'), { from: owner })
    })
    describe('Mock Dai deployment', async () => {
        it('has a name', async () => {
            const name = await daiToken.name()
            assert.equal(name, 'Mock DAI Token')
        })
    })
    describe('Dapp Token deployment', async () => {
        it('has a name', async () => {
            const name = await dappToken.name()
            assert.equal(name, 'DApp Token')
        })
    })
    describe('Token Farm deployment', async () => {
        it('has a name', async () => {
            const name = await tokenFarm.name()
            assert.equal(name, 'Dapp Token Farm')
        })
        it('contract has tokens', async () => {
            let balance = await dappToken.balanceOf(tokenFarm.address)
            assert.equal(balance.toString(), tokens('1000000'))
        })
    })
})
----------------------------
//logs
Contract: TokenFarm
    Mock Dai deployment
      √ has a name (203ms)
    Dapp Token deployment
      √ has a name (98ms)
    Token Farm deployment
      √ has a name (149ms)
      √ contract has tokens (96ms)
  4 passing (3s)
reference:
Wednesday, September 15, 2021
Ethereum Programming 3 testing 1
truffle test
Contract: TokenFarm
    Mock Dai deployment
      1) has a name
    > No events were emitted
  0 passing (662ms)
  1 failing
  1) Contract: TokenFarm
       Mock Dai deployment
         has a name:
      AssertionError: expected 'Mock DAI Token' to equal 'Mock Dai Token'
      + expected - actual
      -Mock DAI Token
      +Mock Dai Token
----------------
//TokenFarm.test.js
const { assert } = require('chai')
const DappToken = artifacts.require('DappToken')
const DaiToken = artifacts.require('DaiToken')
const TokenFarm = artifacts.require('TokenFarm')
require('chai')
    .use(require('chai-as-promised'))
    .should()
contract('TokenFarm', (accounts) => {
    let daiToken
    before(async () => {
        daiToken = await DaiToken.new()
    })
    describe('Mock Dai deployment', async () => {
        it('has a name', async () => {
            const name = await daiToken.name()
            assert.equal(name, 'Mock DAI Token')
        })
    })
})
reference:
https://www.youtube.com/watch?v=XLahq4qyors
Tuesday, September 14, 2021
Sunday, September 12, 2021
Ethereum Programming 2 transfer dapp and dai
truffle migrate --reset
tokenFarm = await TokenFarm.deployed()
truffle(development)> tokenFarm.address
'0x689cB867e929Cdd1c69b78B27fb11DAb86B6393e'
truffle(development)> name = tokenFarm.name()
'Dapp Token Farm'
truffle(development)> mDai = await DaiToken.deployed()
accounts = await web3.eth.getAccounts()
truffle(development)> accounts[1]
'0xBC7000c582225B1086020043f35a8bcE1DA910F6'
truffle(development)> balance = await mDai.balanceOf(accounts[1])
undefined
truffle(development)> balance
BN {
  negative: 0,
  words: [ 51380224, 30903128, 22204, <1 empty item> ],
  length: 3,
  red: null
}
truffle(development)> balance.toString()
'100000000000000000000'
truffle(development)> formattedBalance = web3.utils.fromWei(balance)
'100'
truffle(development)> web3.utils.toWei('1.5', 'Ether')
'1500000000000000000'
---------------------
//migrations/2_deploy_contract.js
const DappToken = artifacts.require('DappToken')
const DaiToken = artifacts.require('DaiToken')
const TokenFarm = artifacts.require('TokenFarm')
module.exports = async function (deployer, network, accounts) {
  // Deploy Mock DAI Token
  await deployer.deploy(DaiToken)
  const daiToken = await DaiToken.deployed()
  // Deploy Dapp Token
  await deployer.deploy(DappToken)
  const dappToken = await DappToken.deployed()
  // Deploy TokenFarm
  await deployer.deploy(TokenFarm, dappToken.address, daiToken.address)
  const tokenFarm = await TokenFarm.deployed()
  // Transfer all tokens to TokenFarm (1 million)
  await dappToken.transfer(tokenFarm.address, '1000000000000000000000000')
  // Transfer 100 Mock DAI tokens to investor
  await daiToken.transfer(accounts[1], '100000000000000000000')
}
--------------------------
//src/componenets/contracts
pragma solidity ^0.5.0;
import "./DappToken.sol";
import "./DaiToken.sol";
contract TokenFarm{
    string public name = "Dapp Token Farm";
    DappToken public dappToken;
    DaiToken public daiToken;
    constructor(DappToken _dappToken, DaiToken _daiToken) public{
        dappToken = _dappToken;
        daiToken = _daiToken;
    }
}
reference:
Saturday, September 11, 2021
Ethereum Programming 1
terminal
truffle compile
truffle migrate
truffle console
truffle(development)> tokenFarm = await TokenFarm.deployed()
truffle(development)> tokenFarm
metamask
github code
reference:
Friday, September 10, 2021
Thursday, September 9, 2021
Monday, September 6, 2021
kivy 51 add ship
 #galaxy.py
import random
from kivy import platform
from kivy.app import App
from kivy.core.window import Window
from kivy.graphics import Line, Rectangle, Color, Quad, Triangle
from kivy.metrics import dp
from kivy.properties import NumericProperty, Clock
from kivy.uix.widget import Widget
class Galaxy(Widget):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.n_vlines = 5
        self.n_hlines = 15
        self.space_vlines = dp(150)
        self.space_hlines = dp(100)
        self.speed_hl = 10
        self.step_hl = 0
        self.clock = 0.05
        self.speed_vl = 10
        self.step_vl = 0
        self.direction_vl = 1
        self.click_press = False
        self.start_x = 0
        self.shift_x = 0
        self.shift_y = 0
        self.n_keydown = 0
        self.tiles = []
        for i in range(12):
            self.tiles.append({"x": 2, "y": i})
        with self.canvas:
            self.vlines = []
            self.hlines = []
            for i in range(self.n_vlines+1):
                vline = Line(points=(0,0,0,100))
                self.vlines.append(vline)
            for j in range(self.n_hlines):
                hline = Line(points=(0,0,100,0))
                self.hlines.append(hline)
            self.rect_l = Rectangle(pos =(0,0), size=(0,0))
            self.rect_r = Rectangle(pos=(0, 0), size=(0, 0))
            self.quads = []
            Color(0,1,0)
            for n in range(30):
                quad = Quad()
                quad.points = [0, 0, 0, 0, 0, 0, 0, 0]
                self.quads.append((quad))
            Color(0,0,1)
            self.ship = Triangle()
        Clock.schedule_interval(self.update, self.clock)
        if platform in ('linux', 'win', 'macosx'):
            self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
            self._keyboard.bind(on_key_down=self._on_keyboard_down)
            self._keyboard.bind(on_key_up=self._on_keyboard_up)
    def on_size(self, *args):
        self.update(0.2)
    def on_touch_down(self, touch):
        self.click_press = True
        if touch.x < self.width/2:
            self.rect_l.pos = (0, self.center_y-dp(50))
            self.rect_l.size = (dp(100), dp(100))
            self.direction_vl = abs(self.direction_vl)
            self.update(0.2)
        else:
            self.rect_r.pos = (self.width-dp(100), self.center_y - dp(50))
            self.rect_r.size = (dp(100), dp(100))
            self.direction_vl = -abs(self.direction_vl)
            self.update(0.2)
    def on_touch_up(self, touch):
        self.click_press = False
        self.rect_l.size=(0,0)
        self.rect_r.size = (0, 0)
    def _keyboard_closed(self):
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)
        self._keyboard.unbind(on_key_down=self._on_keyboard_up)
        self._keyboard = None
    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        print(self.n_keydown)
        self.click_press = False
        if self.n_keydown>0: return False
        #print("keyboard down")
        if keycode[1] == 'left':
            self.click_press = True
            self.n_keydown += 1
            self.rect_l.pos = (0, self.center_y - dp(50))
            self.rect_l.size = (dp(100), dp(100))
            #self.direction_vl = abs(self.direction_vl)
            self.direction_vl = self.space_vlines/self.speed_hl
        elif keycode[1] == 'right':
            self.n_keydown += 1
            self.click_press = True
            self.rect_r.pos = (self.width - dp(100), self.center_y - dp(50))
            self.rect_r.size = (dp(100), dp(100))
            #self.direction_vl = -abs(self.direction_vl)
            self.direction_vl = -self.space_vlines/self.speed_hl
        return True
    def _on_keyboard_up(self, *args):
        #print(*args)
        #print("keyboard up")
        self.n_keydown=0
        self.update(0.2)
        self.rect_l.size = (0, 0)
        self.rect_r.size = (0, 0)
        self.click_press = False
        return True
    def perspective_transform(self, x, y):
        #return x, y
        ratio = (self.height-y)/self.height
        tx = ratio*(self.center_x-x)
        ty = ratio**2
        return self.center_x-tx, 0.8*self.height*(1-ty)
    def tile(self, a, b, n):
        x0 = self.start_x + a * self.space_vlines + self.shift_x
        y0 = b * self.space_hlines - self.shift_y
        x1 = x0
        y1 = y0 + self.space_hlines
        x2 = x0 + self.space_vlines
        y2 = y1
        x3 = x2
        y3 = y0
        _, y0 = self.perspective_transform(x0, y0)
        x0, _ = self.perspective_transform(x0, y0 / 0.8)
        _, y1 = self.perspective_transform(x1, y1)
        x1, _ = self.perspective_transform(x1, y1 / 0.8)
        _, y2 = self.perspective_transform(x2, y2)
        x2, _ = self.perspective_transform(x2, y2 / 0.8)
        _, y3 = self.perspective_transform(x3, y3)
        x3, _ = self.perspective_transform(x3, y3 / 0.8)
        self.quads[n].points = [x0, y0, x1, y1, x2, y2, x3, y3]
    def update(self, dt):
        self.start_x = self.center_x - (int(self.n_vlines / 2)+0.5) * self.space_vlines
        self.shift_x = self.speed_vl * self.step_vl
        """
        if shift_x > self.width or shift_x < -self.width:
            self.direction_vl = -self.direction_vl
        """
        if self.click_press and self.n_keydown==0:
            self.step_vl += self.direction_vl
        for i in range(self.n_vlines+1):
            x = self.start_x + self.space_vlines * i + self.shift_x
            x1, y1, x2, y2 = x, 0, x, self.height
            x1, y1 = self.perspective_transform(x1, y1)
            x2, y2 = self.perspective_transform(x2, y2)
            self.vlines[i].points = (x1, y1, x2, y2)
        self.space_hlines = self.height / self.n_hlines
        self.shift_y = self.speed_hl * self.step_hl
        if self.shift_y > self.space_hlines:
            self.step_hl = 0
        if not self.click_press:
            self.step_hl += 1
        for j in range(self.n_hlines):
            y = j * self.space_hlines - self.shift_y
            x1, y1, x2, y2 = self.start_x + self.shift_x, y, self.width - self.start_x + self.shift_x, y
            _, y1 = self.perspective_transform(x1, y1)
            x1, _ = self.perspective_transform(x1, y1 / 0.8)
            _, y2 = self.perspective_transform(x2, y2)
            x2, _ = self.perspective_transform(x2, y2 / 0.8)
            self.hlines[j].points = (x1, y1, x2, y2)
        for i, tile in enumerate(self.tiles):
            self.tile(tile["x"], tile["y"], i)
            n_tiles = len(self.tiles)
            if self.shift_y > self.space_hlines:
                tile["y"] -= 1
                if tile["y"] < 0:
                    del self.tiles[i]
                    self.quads[n_tiles-1].points = [0, 0, 0, 0, 0, 0, 0, 0]
                    if self.tiles[i+1]["y"] == 0:
                        del self.tiles[i+1]
                        self.quads[n_tiles-2].points = [0, 0, 0, 0, 0, 0, 0, 0]
                    tile_y = self.tiles[-1]["y"]
                    tile_x = self.tiles[-1]["x"] + random.randrange(-1, 2)
                    if tile_x < 0 or tile_x > self.n_vlines-2:
                        tile_x = self.tiles[-1]["x"]
                    if tile_x == self.tiles[-1]["x"]:
                        self.tiles.append({"x": tile_x, "y": tile_y + 1})
                    else:
                        self.tiles.append({"x": tile_x, "y": tile_y})
                        self.tiles.append({"x": tile_x, "y": tile_y + 1})
        x0 = self.center_x - self.space_vlines/2
        y0 = self.space_hlines
        x1 = self.center_x
        y1 = self.space_hlines * 2
        x2 = self.center_x + self.space_vlines/2
        y2 = self.space_hlines
        _, y0 = self.perspective_transform(x0, y0)
        x0, _ = self.perspective_transform(x0, y0 / 0.8)
        _, y1 = self.perspective_transform(x1, y1)
        x1, _ = self.perspective_transform(x1, y1 / 0.8)
        _, y2 = self.perspective_transform(x2, y2)
        x2, _ = self.perspective_transform(x2, y2 / 0.8)
        self.ship.points = [x0, y0, x1, y1, x2, y2]
        if self.shift_y > self.space_hlines:
            self.shift_y = 0
        #print(self.tiles)
class GalaxyApp(App):
    pass
GalaxyApp().run()
reference:
Subscribe to:
Comments (Atom)



















