Assignment ERC721

Create the truffle directory
Implement the IERC721 into your contracts directory.

Implementing IERC721.
Functions created!

pragma solidity >=0.6.0 <0.8.0;

import "./IERC721.sol";
import "../node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";

contract Kittycontract is IERC721 {

    using SafeMath for uint256;

    mapping(address=>uint256) private balances;
    uint256 private totalTokens;
    string private ticker;
    string private tickerName;

    struct tokenOwnersDetails {
        address owner;
        bool created;
    }
    mapping(uint256=>tokenOwnersDetails) private tokenOwners;

    function balanceOf(address owner) external override view returns (uint256 balance) {
        balance = balances[owner];
    }

    function totalSupply() external override view returns (uint256 total) {
        total = totalTokens;
    }

    function name() external override view returns (string memory tokenName) {
        tokenName = tickerName;
    }

    function symbol() external override view returns (string memory tokenSymbol) {  
        tokenSymbol = ticker;
    }

    function ownerOf(uint256 tokenId) external override view returns (address owner) {
        require(tokenOwners[tokenId].created, "Token does not exist");

        owner = tokenOwners[tokenId].owner;
    }

    function transfer(address to, uint256 tokenId) external override {
        require(to != address(0), "TO address must be defined.");
        require(to != address(this), "Cannot transfer to the contract itself");
        require(tokenOwners[tokenId].created, "Token ID does not exist.");
        require(tokenOwners[tokenId].owner == msg.sender, "Only the Token owner can transfer it.");

        tokenOwners[tokenId].owner = to;

        balances[to] = balances[to].add(1);
        balances[msg.sender] = balances[to].sub(1);

        emit Transfer(msg.sender, to, tokenId);
    }

}
1 Like
ERC721 Assignment code
pragma solidity ^0.5.12;

import "./IERC721.sol";

contract CryptoBears is IERC721 {

    string public constant bearTokenName = "CryptoBears";   //Token Name
    string public constant bearTokenSymbol = "CB";          //Token Symbol
    
    struct Bear {
        uint256 genes;
        uint64 birthTime;
        uint32 mumId;
        uint32 dadId;
        uint16 generation;
    }

    Bear[] bears;

    
    mapping(address => uint256) tokenOwnershipCount; //Token owners balance
    mapping(uint256 => address) public tokenIdOwnerMapping; //Maps TokenId to owners address

    

     function balanceOf(address owner) external view returns (uint256 balance){
         return tokenOwnershipCount[owner];
     }

      function totalSupply() public view returns (uint256 total){
          return bears.length;
      }

      function name() external view returns (string memory tokenName){
          return bearTokenName;
      }

    function symbol() external view returns (string memory tokenSymbol){
        return bearTokenSymbol;
    }

     function ownerOf(uint256 tokenId) external view returns (address owner){
        return tokenIdOwnerMapping[tokenId];
     }

     function transfer(address to, uint256 _tokenId) external {
         require(_owns(msg.sender, _tokenId), "You are not the owner of this token!");
         require(to != address(0), "You cannot send tokens to this address!");
         require(to != address(this), "You cannot send tokens to this address!");

         _transfer(msg.sender, to, _tokenId);

         
     }

     function _transfer(address _from, address _to, uint256 _tokenId) internal {
            tokenOwnershipCount[_to]++;

            tokenIdOwnerMapping[_tokenId] = _to;

            if(_from != address(0)){
                tokenOwnershipCount[_from]--;
            }

            emit Transfer(_from, _to, _tokenId);
     }

     function _owns(address _claimant, uint256 _tokenId) internal view returns(bool) {
         return tokenIdOwnerMapping[_tokenId] == _claimant;
     }
}



1 Like
ERC721 First Assignment
pragma solidity 0.8.3;

import "./IERC721.sol";

contract catContract is IERC721 {

    mapping (address => uint256) private _balances;

    mapping (uint256 => address) private _ownerOf;

    uint256 _totalSupply = 100;

    string private _name = "Gato";

    string private _symbol = "GAT";
 
     
    function balanceOf(address owner) external override view returns (uint256 balance){
        return _balances[msg.sender];
    }

     
    function totalSupply() external override view returns (uint256 total){
        return _totalSupply;
    }

    
    function name() external view override returns (string memory tokenName){
        return _name;
    }

    
    function symbol() external view override returns (string memory tokenSymbol){
        return _symbol;
    }

    function ownerOf(uint256 tokenId) external view override returns (address owner){
        return _ownerOf[tokenId]; 
    }

/* @dev Transfers `tokenId` token from `msg.sender` to `to`.
     *
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `to` can not be the contract address.
     * - `tokenId` token must be owned by `msg.sender`.
     *
     * Emits a {Transfer} event.
     */

    function transfer(address to, uint256 tokenId)override external{
        require(to != address(0), "Don't send it to 0");
        require(to != address(this),"Don't send to the contract");
        require(_ownerOf[tokenId] == msg.sender, "must be the owner");
        event Transfer(msg.sender, to, tokenId);
    }

}

Just watched Philips video, will fix the totalSupply function and the state variable as well :frowning:

Had to add the owns function after watching the solution video. Here is my code:

pragma solidity ^0.8.3;

import "./IERC721.sol";
import "../node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";


contract Catcontract is IERC721 {
using SafeMath for uint256;

string private  constant Name = "Purrfect";
string private constant Symbol = "PURR";

struct Cat {
    uint256 genes;
    uint64 birthTime;
    uint32 mumId;
    uint32 dadId;
    uint16 generation;
}
Cat[] cats;
//      owner      amount
mapping(address => uint256) ownerTokenBalance;

//      tokenId    owner of cat
mapping(uint256 => address) public catIndexToOwner;

    function balanceOf(address owner) external override view returns (uint256 balance){
        balance = ownerTokenBalance[owner];
        return balance;
    }

    function totalSupply() external override view returns (uint256 total){
        total = cats.length;
        return total; 
    }

    function name() external override pure returns (string memory tokenName){
        tokenName = Name;
        return tokenName;
    }

    function symbol() pure external override returns (string memory tokenSymbol){
        tokenSymbol = Symbol;
        return tokenSymbol;
    }

    function ownerOf(uint256 tokenId) external override view returns (address owner){
        return catIndexToOwner[tokenId];
    }

    function transfer(address to, uint256 tokenId) external override{
        require(to != address(0), "Cannot Send Tokens To This Address");
        require(to != address(this), "Cannot Send Tokens To This Address");
        require(owns(msg.sender, tokenId), "You Must Own The Token You Are Sending");

        ownerTokenBalance[to] = ownerTokenBalance[to].add(1);
        ownerTokenBalance[msg.sender] = ownerTokenBalance[msg.sender].sub(1);
        
        emit Transfer(msg.sender, to, tokenId);
    }

    function owns(address claimant, uint256 _tokenId) internal view returns (bool){
        return catIndexToOwner[_tokenId] == claimant;
    }

}
1 Like

I would do the following since we discussed this in the new Smart Contract Programming 201 course :).

pragma solidity >=0.4.22 <0.9.0;

import '../node_modules/@openzeppelin/contracts/access/Ownable.sol';
import '../node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol';
import '../node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol';

//import "./IERC721.sol";

contract Kittycontract is ERC721{

}

I’ll try to make a json version of the struct and see if I can get it to work as we progress. Probably will have to use an oracle or IPFS. If I get stuck I’ll just follow implementation as per video.

2 Likes

Hi @dan-i @filip

How do I change from truffle(development) to truffle(ganache) in the Terminal ?
I successfully migrated the contract through truffle using ganache (because the Ganache shows my Migrations and Kittycontract deployment , but later when i enter command in my terminal as below :
“truffle console”

and press ENTER

then the terminal shows truffle(development) instead of truffle(ganache)

I am now completing the Dapp Intro Course and I have already done my Smart contract 101 and 201 courses, and i remember someone had mentioned in the forum (maybe @dan-i) on how to change from truffle(development) to truffle(ganache) , But i am now revisiting the 101 course forum and I am unable to find / locate the answer …

Can you please help me ???

Thanks and regards

Su.Kal Crypto

Screenshot 2021-04-26 at 9.09.48 PM
Screenshot 2021-04-26 at 9.10.16 PM
Screenshot 2021-04-26 at 9.10.48 PM
Screenshot 2021-04-26 at 9.11.35 PM

Hi,

So i again tried to migrate --reset and I note that the network name: development , which means maybe my port is wrong ( and indeed i saw in truffle config its as follows :slight_smile:

networks: {
    // Useful for testing. The `development` name is special - truffle uses it by default
    // if it's defined here and no other network is specified at the command line.
    // You should run a client (like ganache-cli, geth or parity) in a separate terminal
    // tab if you use this network and you must also set the `host`, `port` and `network_id`
    // options below to some value.
    //
    development: {
     host: "127.0.0.1",     // Localhost (default: none)
     port: 7545,            // Standard Ethereum port (default: none)
     network_id: "*",       // Any network (default: none)
    },

And Later i tried to change that to 8545 Default port, and try to link truffle-config.js again, and later try to migrate --reset, i get the following Terminal error:
Screenshot 2021-04-27 at 5.02.27 PM

Now I am, checking my Metamask Settings too and find everything ok there?

see below :point_down:

Screenshot 2021-04-27 at 5.07.36 PM
Where am i Going wrong ? and if I am wrong then why the contracts are getting deployed using ganache in the first place (using Port : 7545) but later i am not able to interact with ganache using truffle on the terminal >> ?? and when i shift to 8545: it shows the ethereum client RPC error ???
Please give me a detailed explanation as well, so i can become a better developer :slight_smile:
Thanks a ton :pray:
Thanks and Regards

Su.Kal

Gentle Reminder : **How do i change from truffle(development) to truffle(ganache) in the console ??

I have been waiting for a few days now to this answer **

Thanks and Regards

Su.Kal Crypto

Hey @Su.kal.Crypto in order to change the network you just add --network ganache when you initialize migration.

This also depends on your truffle-config file. Let me share you one of mine as an example:

2021-05-01_11h00_06

So you use it in terminal:

2021-05-01_11h04_51

Hopes this solve your Doubts.

1 Like

Hi Kenn
No the problem isn’t getting solved…
If you see my entire issue (see earlier thread above :point_up:), you will see that my ganache is working (the contracts are deploying and its showing on ganache) but in the terminal i am unable to shift from truffle(development) to truffle(ganache)

Anyways, i tried with your methods and its showing the below errors: :point_down:

Screenshot 2021-05-01 at 6.07.10 PM
Screenshot 2021-05-01 at 6.30.29 PM

So Should i just uninstall and re download my Ganache or what do you suggest ??

Thanks and Regards

Su.Kal

Ok I understand your issue now. So first of all, the command for specific network is like this:

2021-05-01_15h37_24

As you see, is using --network ganache . But in order to use this command, also will have to change your ganache port like same of your truffle-config file. Should match the port.

2021-05-01_15h42_00

1 Like

Assignment:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./IERC721.sol";

contract Doracontract is IERC721{
  string private name = "CryptoDoraemon";
  string private symbol = "DORA";

  struct Doraemon {
    uint256 genes;
    uint64 birthTime;
    uint32 mumId;
    uint32 dadId;
    uint16 generation;
  }

  //Array with all token ids (index==>token id)
  Doraemon[] private allTokens;
  //Mapping owner address to token count
  mapping (address => uint256) private ownerToBalance;
  // Mapping from token ID to owner address
  mapping (uint256 => address) private tokenToOwner;

  function totalSupply() public view override returns(uint256){
    return allTokens.length;
  }

  function balanceOf(address _owner) public view override returns(uint256){
    return ownerToBalance[_owner];
  }

  function ownerOf(uint256 _tokenId) public view override returns(address){
    address owner = tokenToOwner[_tokenId];
    require(owner != address(0), "ERC721: owner query for nonexistent token");
    return owner;
  }

  function transfer(address _to, uint256 _tokenId) public override{
    require(_to != address(0) && _to != address(this), "ERC721: invalid address");
    require(_to != msg.sender, "ERC721: cannot send to yourselves");
    require(_to == ownerOf(_tokenId), "ERC721: you are not the owner of this token");
  }

  function _transfer(address _from, address _to, uint256 _tokenId) internal{
    ownerToBalance[_to]++;
    if(_from != address(0)){
      ownerToBalance[_from]--;
    }
    tokenToOwner[_tokenId] = _to;
    emit Transfer(_from, _to, _tokenId);
  }
}

However, I get this weird error:

Contract "Doracontract" should be marked as abstract.

I know that I should put abstract but why is that?

Ok, fixed it

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";
// import "../node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
// import "../node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";

import "./IERC721.sol";

contract Doracontract is IERC721{
  string constant _name = "CryptoDoraemon";
  string constant _symbol = "DORA";

  struct Doraemon {
    uint256 genes;
    uint64 birthTime;
    uint32 mumId;
    uint32 dadId;
    uint16 generation;
  }

  //Array with all token ids (index==>token id)
  Doraemon[] private allTokens;
  //Mapping owner address to token count
  mapping (address => uint256) private ownerToBalance;
  // Mapping from token ID to owner address
  mapping (uint256 => address) private tokenToOwner;

  function totalSupply() public view override returns(uint256){
    return allTokens.length;
  }

  function name() external pure override returns (string memory){
    return _name;
  } 

  function symbol() external pure override returns (string memory){
    return _symbol;
  } 

  function balanceOf(address _owner) external view override returns(uint256){
    return ownerToBalance[_owner];
  }

  function ownerOf(uint256 _tokenId) public view override returns(address){
    address owner = tokenToOwner[_tokenId];
    require(owner != address(0), "ERC721: owner query for nonexistent token");
    return owner;
  }

  function transfer(address _to, uint256 _tokenId) public view override{
    require(_to != address(0) && _to != address(this), "ERC721: invalid address");
    require(_to != msg.sender, "ERC721: cannot send to yourselves");
    require(_owns(msg.sender, _tokenId), "ERC721: you are not the owner of this token");
  }

  function _transfer(address _from, address _to, uint256 _tokenId) internal{
    ownerToBalance[_to]++;
    if(_from != address(0)){
      ownerToBalance[_from]--;
    }
    tokenToOwner[_tokenId] = _to;
    emit Transfer(_from, _to, _tokenId);
  }

  function _owns(address _claimant, uint256 _tokenId) internal view returns(bool){
    return tokenToOwner[_tokenId] == _claimant;
  }
}

Basically, I needed to create all functions defined in the interface. Even the name() and symbol() functions.

1 Like

Thanks a Ton… Resolved

1 Like

Hi All,

My code:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "./IERC721.sol";

abstract contract Kittycontract is IERC721 {

   string tokenName;
   string tokenSymbol;
    constructor(string memory _name, string memory _symbol){
        tokenName =_name;
        tokenSymbol = _symbol;
    }

    struct Kitty {
        uint genes;
        uint birthTime;
        uint mumID;
        uint dadID;
        uint generation;
    }

    Kitty [] kitties;

    mapping(address => uint256) ownershipTokenCount;
    mapping(uint256 => address) public kittyIndexToOwner;

    function balanceOf(address owner) external override view returns (uint256 balance){
        return ownershipTokenCount[owner];
    }

    function totalSupply() external override view returns (uint256 total){
        return kitties.length;
    }

    function name() external override view returns (string memory _name){
        _name = tokenName;
    }
    function symbol() external override view returns (string memory _symbol){
        _symbol = tokenSymbol;
    }
    function ownerOf(uint256 tokenId) external override view returns (address owner){
        return kittyIndexToOwner[tokenId];
    }

    function transfer(address to, uint256 tokenId) external override {
        require(address(this)!= to);
        require(address(0)!= to);
        require(_owns(msg.sender, tokenId));
        _transfer(msg.sender, to, tokenId);
    }
    function _owns(address _claimant, uint256 _tokenId) internal view returns(bool){
        return kittyIndexToOwner[_tokenId] == _claimant;
    }
    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        ownershipTokenCount[_to] ++;
        kittyIndexToOwner[_tokenId] = _to;

        if(_from != address(0)){
            ownershipTokenCount[_from] -- ;
        }
        emit Transfer(_from, _to, _tokenId);
    }
}
Token Contract Code
pragma solidity 0.8.0;

import "./IERC721.sol";

contract NFTToken is IERC721 {

    string public constant _name = "Abstractions";
    string public constant _symbol = "ABS";

    struct Abstraction{
        uint genes;
        uint64 birthTime;
        uint32 mumId;
        uint32 dadId;
        uint16 generation;
    }

    Abstraction[] allAbstractions;

    mapping(uint => address) _tokenApprovals;
    mapping(address => uint) ownershipTokenCount;
    mapping(uint => address) ownership;

    function balanceOf(address owner) external view override returns (uint256 balance) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return ownershipTokenCount[msg.sender];
    }

    function totalSupply() external view override returns (uint256 total) {
        return allAbstractions.length;
    }

    function name() external pure override returns (string memory) {
        return _name;
    }
    function symbol() external pure override returns (string memory) {
        return _symbol;
    }

    function ownerOf(uint256 tokenId) external view override returns (address owner) {
        require(ownership[tokenId] != address(0));
        return ownership[tokenId];
    }

    function transfer(address to, uint256 tokenId) external  override {
        require(to != address(0));
        require(to != address(this));
        require(ownership[tokenId] == msg.sender);

        // Approve
        _tokenApprovals[tokenId] = to;
        emit Approval(msg.sender, to, tokenId);

        _transfer(msg.sender, to, tokenId);
    }

    function _transfer(address from, address to, uint tokenId) internal {
        if (from != address(0)) {
            ownershipTokenCount[msg.sender] -= 1;
        }
        ownershipTokenCount[to] += 1;
        ownership[tokenId] = to;

        emit Transfer(msg.sender, to, tokenId);
    }
}
1 Like

My code implementing ERC721
I tried to use openzepelling but I had some problems because I would need to implement more functions instead I used the normal interface IERC721 (by now)
I tested the contract and worked(on the constructor I assigned a kitty for the person who deployed it)

KittyContract.sol

//SPDX-License-Identifier: MIT
//pragma solidity >=0.4.22 <0.9.0
pragma solidity ^0.8.4;
import "./IERC721.sol";
//import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "../node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";

contract kittyContract is IERC721 {
    using SafeMath for uint256;

    constructor(){ // assign the first kitty to the person who deploy the contract 
        ownershipTokenCount[msg.sender] ++;
        ownershipTokenID[1] = msg.sender;
        uint256 firstDNA = 1111;
        Kitty memory _kitty = Kitty({
            DNA: firstDNA
            });
        kitties.push(_kitty);
    }

    mapping (address => uint256) private ownershipTokenCount;
    mapping (uint256 => address) private ownershipTokenID;

    string  constant  tName = 'Kitty Token';
    string  constant tSymbol = 'KTC';

    struct Kitty {
        uint256 DNA;// DNA frontend
    }
    Kitty[] kitties;

    function balanceOf(address owner) external view override returns (uint256 balance){
        return ownershipTokenCount[owner];
    }

    function totalSupply() external view override returns (uint256 total) {
        return kitties.length;
    }

    function name() external view override returns (string memory tokenName) {
        return tName;
    }

    function symbol() external view override  returns (string memory tokenSymbol) {
        return tSymbol;
    }

    function ownerOf(uint256 tokenId) external view override returns (address owner) {
        return ownershipTokenID[tokenId];
    }

    function transfer(address to, uint256 tokenId) external override  payable {
        require(to != address(0)); //`to` cannot be the zero address.
        require(to != address(this)); // to` can not be the contract address.
        require(owns(msg.sender, tokenId));    // tokenId` token must be owned by `msg.sender`
        ownershipTokenCount[msg.sender] -= 1;
        ownershipTokenID[tokenId] = to;
        ownershipTokenCount[to] += 1;
        emit Transfer(msg.sender, to, tokenId); // Emits a {Transfer} event.
    }

    function owns(address claimant, uint256 tokenId) internal view returns (bool) {
      return ownershipTokenID[tokenId] == claimant;
    }

}
truffle(develop)> accounts
[
  '0x3dD4fA6633b917895E583608b554A7d7f94ad545',
  '0xb20417b79Ec4042718E66E0b87647007e47b65B9',
  '0xc681F4f0943cFad14B7bc9747BCD4A1c676a9D37',
  '0xD450187BBc710A83650d3C6dfDe7340Fa3c85668',
  '0xab4FEF9f74bD5f119Dfd573800C4d88d1d99FeB9',
  '0xF3698c3CDc59df02E0241eb3ab59166C333D23e6',
  '0x8bbda25897b002FC836Ba8753e0f338F6dB30136',
  '0x177642693faAbb42598184B95872893cb84ADc25',
  '0x52dddD4d5Ad751E526911F16361ccab0250bfd3D',
  '0xB14AE351571bc8D26958aac6A2B14fDD243E5068'
]
truffle(develop)> instance.totalSupply()
BN { negative: 0, words: [ 1, <1 empty item> ], length: 1, red: null }
truffle(develop)> instance.symbol()
'KTC'
truffle(develop)> instance.name()
'Kitty Token'
truffle(develop)> instance.balanceOf('0x3dD4fA6633b917895E583608b554A7d7f94ad545')
BN { negative: 0, words: [ 1, <1 empty item> ], length: 1, red: null }
truffle(develop)> instance.balanceOf('0xb20417b79Ec4042718E66E0b87647007e47b65B9')
BN { negative: 0, words: [ 0, <1 empty item> ], length: 1, red: null }
truffle(develop)> instance.ownerOf(1)
'0x3dD4fA6633b917895E583608b554A7d7f94ad545'
truffle(develop)> instance.transfer('0xb20417b79Ec4042718E66E0b87647007e47b65B9', 1, {value: web3.utils.toWei('1', 'ether')})
{
  tx: '0xbbbb6f94dc1853093a3dd46a0d73fcd2e83e7bd5c4ae5fd75551053bf061bb7c',
  receipt: {
    transactionHash: '0xbbbb6f94dc1853093a3dd46a0d73fcd2e83e7bd5c4ae5fd75551053bf061bb7c',
    transactionIndex: 0,
    blockHash: '0x72d18ea92c482b8ba82e8045a8308b194c935a848c0e02f50b0d7243e594f933',
    blockNumber: 5,
    from: '0x3dd4fa6633b917895e583608b554a7d7f94ad545',
    to: '0x56ab74239f45b65a26ec3a2226ddef195227f53e',
    gasUsed: 43417,
    cumulativeGasUsed: 43417,
    contractAddress: null,
    logs: [ [Object] ],
    status: true,
    logsBloom: '0x00000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000040000000000000000000000000008000000000000000000040000000000000000000040000000000000000000000000000000000000000000000000010010000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000002000000000000000000000040000000040000000040000000000000000000000000000000000000000000000000',
    rawLogs: [ [Object] ]
  },
  logs: [
    {
      logIndex: 0,
      transactionIndex: 0,
      transactionHash: '0xbbbb6f94dc1853093a3dd46a0d73fcd2e83e7bd5c4ae5fd75551053bf061bb7c',
      blockHash: '0x72d18ea92c482b8ba82e8045a8308b194c935a848c0e02f50b0d7243e594f933',
      blockNumber: 5,
      address: '0x56aB74239F45B65a26Ec3a2226Ddef195227f53e',
      type: 'mined',
      id: 'log_1ca0b98f',
      event: 'Transfer',
      args: [Result]
    }
  ]
}
truffle(develop)> instance.balanceOf('0xb20417b79Ec4042718E66E0b87647007e47b65B9')
BN { negative: 0, words: [ 1, <1 empty item> ], length: 1, red: null }
truffle(develop)> instance.balanceOf('0x3dD4fA6633b917895E583608b554A7d7f94ad545')
BN { negative: 0, words: [ 0, <1 empty item> ], length: 1, red: null }
truffle(develop)>
1 Like
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "../OpenZeppelin/node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "../OpenZeppelin/node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";

abstract contract SupplyChainProtocol is IERC721 {
    using SafeMath for uint256;
  


}

For my ERC721 token, I decided to soft fork from Crypto Kitties and hard fork from Centrifuge and the creation of a Supply Chain Protocol dApp. Blockchain has been applied to individual products, invoices, and other parts of the supply chain. I decided to utilize an NFT as a supply chain order for responsiveness, efficiency, and traceability. The idea stemmed from Centrifuge, who constructed an NFT as an invoice in collateralized finance. After researching the supply chain industry, I found that collateralized finance applies to obtaining funds or supplies to begin the supply chain but did not hit the main painpoints(low responsiveness, always reactive management, and speculative ordering. As we know, there are public and private blockchains and many large companies elect to use private blockchains. Utilizing an NFT to represent a purchase order does a better job overall to hit some the major supply chain painpoints. After speaking with my instructor, we found that utilizing a DAO was not neccessary for the exchange of the NFT because of high gas and transaction fees associated with Ethereum.


1. // SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;
import "../OpenZeppelin/node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "../OpenZeppelin/node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";

abstract contract SupplyChainProtocol is IERC721 {
    using SafeMath for uint256;
    string public constant orderTokenName = "Supply Chain Protocol";
    string public constant orderTokenSymbol = "SCP"; 
    constructor(string memory _name, string memory _symbol){
        _name= "Supply Chain Protocol";
        _symbol="SCP";
    }
  struct Order{
      uint256 id;
      uint64 timeStamp;
      uint64 cost;
      string productName;
      string description;
      uint64 leadTime_in_days;
    }
    Order[] orderVolume;
    struct tokenOwnersDetails {
        address owner;
        bool created;
    }
    mapping(address => uint256) timeStamps;
    mapping(address => uint256) private balances;
    mapping(address => uint256) orders;
    mapping(address => uint256) OrderIncites;
    mapping(uint256 => tokenOwnersDetails) private orderIdMapping;

    function name() external view virtual returns (string memory) {
    return orderTokenName;
    }
    function symbol() external view virtual returns (string memory){
    return orderTokenSymbol;
    }
    function totalSupply() external view returns (uint256 total){
        total = orderVolume.length;
        return total; 
    }   
    function balanceOf(address owner) external view override returns (uint256 balance){
        return OrderIncites[owner];
    }
    function ownerOf(uint256 tokenId) external view override returns (address owner){
        require(orderIdMapping[tokenId].created);
        return owner = orderIdMapping[tokenId].owner;
    }
    
    function transfer(address from, address to, uint256 tokenId) external{
        require(address(to) != address(0));
        require(address(from) != address(0));
        require(orderIdMapping[tokenId].created);
        require(orderIdMapping[tokenId].owner==msg.sender);
        orderIdMapping[tokenId].owner=to;
        balances[to] = balances[to].add(1);
        balances[msg.sender] = balances[to].sub(1);
        emit Transfer(msg.sender, to, tokenId);
    }
    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        balances[_to]++;
        _to=orderIdMapping[_tokenId].owner;
        if(_from != address(0)) {
            balances[_from]--;
        }
        emit Transfer(_from, _to, _tokenId);

    }
    function _owns(address _claimaint, uint256 _tokenId) internal view returns(bool){
        return orderIdMapping[_tokenId].owner == _claimaint;
    }
   
   
}

image