BD Flashcards

1
Q

The difference between –save and –save-dev is

A

–save gets added to the dependencies and –save-dev gets added to devDependencies which is libraries you only need for your development environment

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

The Zsh equivalent of .bash_profile is

A

.zshenv

note: Zsh does not source .bash_profile, .bashrc

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

The first line in a solidity contract is

A

pragma solidity >=0.7.0 <0.9.0;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Contract names are written in

A

contract CapitalCase

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

To write a getter function in solidity, type

A

function get() public view returns(string) {
return var_name;
}

or

string public varName;

Note: Setters are not generated, only getters for public/external top level variables

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Variable names are written in

A

camelCase

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

The 4 contract memory locations are

A

storage, memory, stack, calldata

storage: stored in the blockchain
memory: stored in memory and disappears after function runs, can be passed to other functions
stack: a variable that only exists inside a function and ceases to exist after function runs. A plain variable declaration in a function is automatically stored in stack.
calldata: Must be used for arguments to functions that are public or external. Like, literally data from a call.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

To create an array, type

A

type[10]

arrays in solidity must all have the same type

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

To create a variable for an ethereum address type

A

address varName = “string”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Top level variables that have no memory location tag are automatically saved to

A

storage

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

To write a setter function in solidity, type

A

function set(string _paramName) external {
varName = _paramName;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

The 4 function visibility keywords are

A

private: Only the smart contract can call the function (use underscore on func name as convention)
internal: Only the smart contract can call the function or the smart contract that inherited this function
external: Can only be called from outside the smart contract
public: Can be called from inside and outside the contract

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

The 4 function visibility keywords are

A

private, internal, external, public

private: Only the smart contract can call the function (use underscore on func name as convention)
internal: Only the smart contract can call the function or the smart contract inherited this function
external: Can only be called from outside the smart contract
public: Can be called from inside and outside the contract

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Variables with no visibility keyword default to

A

private

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Remix will not let me deploy without starting with

A

// SPDX-License-Identifier: GPL-3.0

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

People can only run your smart contract’s functions on ether scan if you

A

upload your source code

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

An interface is

A

A group of function signatures (everything before the curly braces) that match ones present in a different contract. You define them in order to be able to call that remote contract’s functions in your own contract.

Each interface only connects to one contract.

interface MyInterface {
function remoteFunc() external view returns (uint);
}

Then to call the remote function in my contract, type

MyInterface(remoteContractAddress).remoteFunc();

Note: For some reason, interface functions must be external even though the original function might be public and it still works.
I do not need to copy the virtual/override from the signature.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

msg.sender is

A

the address of the person or contract calling your function. The msg variable is global.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

msg.value is

A

the amount of gwei being sent to your contract from the person calling your function.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

The difference between tx.origin and msg.sender is

A

tx.origin is the original person to initiate a transaction and msg.sender can be an intermediate contract triggered by the original person.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

To throw an error if a value is negative, type

A

require(false, “Error message”)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

To send ether to an address, type

A

(bool success, ) = address(“address”).call{value: 1 ether}(“”);
require(success);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

For a smart contract to receive ether, it must have at least one function with

A

a payable tag

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

To make your contract able to receive ether, add the function

A

receive() external payable { … }

Or make any function payable, but that might require the sender to call it in a more sophisticated way (like in a UI or using an interface), rather than simple send from any wallet.

note: Contracts can only have one receive function

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

The fallback() function is called when someone

A

calls a contract with non empty calldata but no other function matches

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

To make an array of payable addresses, type

A

address payable[] public arrayVar

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

To set the owner of a contract to the person that deploys it, type

A

address owner;
address param;
constructor(string passedInParam) {
// initialize the owner on deployment
owner = msg.sender;
param = passedInParam;
}

Note: Useful for when you need one person to be able to run important functions.

You need to initialize the empty variables above the constructor before it updates them.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
28
Q

To cast a msg.sender address into a payable address, type

A

payable(msg.sender)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
29
Q

To add to an array at the end, type

A

arrayName.push(itemName)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
30
Q

To get the balance of your own smart contract, type

A

address(this).balance

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
31
Q

To remove all the elements of an array, type

A

delete arrayName

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
32
Q

If variables are declared outside a function, changing them inside a function will still

A

update the storage on the blockchain

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
33
Q

The protocol id for NFTs is

A

ERC-721

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
34
Q

To inherit the functions and variables from a parent contract, type

A

contract ChildContract is ParentContract {

}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
35
Q

To pass an argument to the constructor function of a parent contract, type

A

constructor() public ParentContractName(“param_1”) { … }

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
36
Q

To inherit multiple contracts, type

A

contract ChildContract is ParentContract1, ParentContract2 { … }

If multiple parents have the same function, the last in the list overrides the previous. The convention is to order from most base to most derived.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
37
Q

To inherit multiple contracts, type

A

contract ChildContract is ParentContract1, ParentContract2 { … }

If multiple parents have the same function, the last in the list overrides the previous

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
38
Q

The difference between a contract that is basic vs derived

A

derived inherits from more contracts

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
39
Q

To create an event, type

A

event EventName(type varName, type varName)

Note: using “indexed” makes that field filterable, but its expensive.

to emit an event, type
emit EventName(varName,varName)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
40
Q

To allow external consumers to filter out events based on the value on one of the fields, type

A

event EventName(type indexed varName, type varName)

Only 3 fields can have indexed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
41
Q

Events cannot be read by

A

smart contracts. They are read by listeners using web3/ethers.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
42
Q

Use the storage memory location if you need

A

the variable change to persist after the function ends/create a transaction. It writes to the blockchain.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
43
Q

To set unique permissions on a function use

A

require() at the beginning of it so the function errors if the expression is false

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
44
Q

A good way to model people into a variable is

A

struct Person {
uint height;
bool alive;
address friend;
}

mapping(address => Person) public people;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
45
Q

To create a modifier that only allows the owner to run a function, type

A

modifier onlyOwner() {
require(owner == msg.sender, “Ownable: caller is not the owner”);
_;
}

import “@openzeppelin/contracts/access/Ownable.sol”;

contract MyContract is Ownable {
function myFunc() public onlyOwner {}
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
46
Q

To map an NFT to an owner, type

A

mapping(uint256 => address) private _owners;

Dom did it like this:
// Mapping from owner to list of owned token IDs
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
47
Q

You cannot know what NFTs an address holds because

A

there is no index to search. You would either have to use a function in the smart contract that maps an owner address to an NFT id, or set up a listener for Transfer events that constantly updates your database.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
48
Q

To verify a user has the key to a wallet, you essentially need to

A

create a random nonce, have them sign it with metamask.

Cryptokitties has the correct workflow.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
49
Q

Metamask automatically injects

A

an object called ethereum that you can call functions on to do stuff

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
50
Q

To see a user’s wallet addresses using metamask, type

A

ethereum.request({ method: ‘eth_requestAccounts’ }).then(data => console.log(data))

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
51
Q

To sign a message using metamask, type

A

Note: In order use this, you must first use ‘eth_requestAccounts’

var from = “0xf7c3abd77184cdbc9417890820b3ffcfe4bcd333”
var msg = “Hi there” // Prob need to cast to hex
var params = [msg, from]
var method = ‘personal_sign’

ethereum.request({method, params}).then(data => console.log(data))

or

ethereum.request({method, params, from}).then(data => console.log(data))

After I sign into cryptokitties, they send my wallet address and my encrypted message to their server and their server sends me back another token. If I can successfully extract their real wallet address from the signed message just using the initial message and the token, then it means they successfully signed it with their secret.

For some reason crypto kitties sends back a token and saves it under a tokens cookie after my wallet address.

“To summarize this block, what it does is, given our msg (containing the nonce) and our signature, the ecrecover function outputs the public address used to sign the msg. If it matches our publicAddress from the request body, then the user who made the request successfully proved their ownership of publicAddress. We consider them authenticated.”

This explains the backend decently.
https://www.toptal.com/ethereum/one-click-login-flows-a-metamask-tutorial#lets-build-it-together

This post shows the steps necessary to get public address from signed message
https://ethereum.stackexchange.com/questions/12571/getting-an-address-from-ethereumjs-utils-ecrecover

ethereumJSUtils works in node
https://github.com/ethereumjs/ethereumjs-util

Closest solution
https://ethereum.stackexchange.com/questions/35486/how-to-verify-metamask-account-holder-is-the-real-owner-of-the-address?noredirect=1&lq=1

https://ethereum.stackexchange.com/questions/35486/how-to-verify-metamask-account-holder-is-the-real-owner-of-the-address

https://ethereum.stackexchange.com/questions/54715/metamask-verification-on-a-server-with-web3-personal-sign?noredirect=1&lq=1

https://github.com/danfinlay/js-eth-personal-sign-examples/blob/master/index.js

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
52
Q

How synthetic loot works is basically

A

it uses your wallet address as a seed to deterministically choose all the items. If you make a ton of wallets, then it will make a ton of loots.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
53
Q

Adding the –global tag to npm install makes

A

makes the package available in any shell and not just inside the current project

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
54
Q

npm only manages

A

server side packages. Not front end. There are other front end package managers. It’s called NODE package manager.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
55
Q

To signal the intent that a function can be overridden by a contract that inherits it

A

add the modifier “virtual”

function myFunc() virtual public returns(uint) {…}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
56
Q

To run the scripts with async functions in hardhat reliably, people usually

A

use an async function and then put await before all async calls

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
57
Q

To control a contract using ethers, type

A

Ethers always expects you to give it and returns BigNumbers instead of regular js numbers. eg ethers.BigNumber.from(5)

To pass values to a contract constructor deployed by ethers
add as arguments to the deploy function.

Ethers.js returns the transaction data instead of the contract function return value, if the function requires creating a transaction. This means if I want to get the return, I’ll need to set it to a function and then create a getter function.

To deploy a contract

const contractTemplate = await ethers.getContractFactory(“Token”)
const myDeployedContract = await contractTemplate.deploy()
await myDeployedContract.deployed()

then you can use
myDeployedContract.address
await myDeployedContract.contractFunction()

Note: Contracts must have an owner. Ethers automatically uses the first signer from const [owner] = await ethers.getSigners() as the owner. It is best to call that ourselves as well so we can have access to it.

To call a contract function from a different address than owner, type
const [owner, addr1, addr2] = await ethers.getSigners()
await myDeployedContract.connect(addr1).contractFunction()

To explicitly choose the address of the signer, type
accounts = await window.ethereum.request({ method: ‘eth_requestAccounts’ });
provider = new ethers.providers.Web3Provider(window.ethereum);
signer = provider.getSigner(accounts[0]);

To create a signer, type
new ethers.Wallet(private_key, optional_provider)

To call a payable function, you need to add as a third argument
overrides = {
// To convert Ether to Wei:
value: ethers.utils.parseEther(“1.0”) // ether in this case MUST be a string
// Or you can use Wei directly if you have that:
// value: someBigNumber
// value: 1234 // Note that using JavaScript numbers requires they are less than Number.MAX_SAFE_INTEGER
// value: “1234567890”
// value: “0x1234”
// Or, promises are also supported:
// value: provider.getBalance(addr)
};

await MintingPress.mintToken(1, overrides)

To return a public variables in ethers, just call the exact variable name as a function

To create an event listener in ethers, type

filter = {
address: dwede, // Omit to listen to all addresses
topics: [
utils.id(“Transfer(address,address,uint256)”),
]
}

provider.on(filter, (data) => { … })

in hardhat, ethers is added to the global scope in the scripts folder, so you dont need to instantiate it, it instantiates based on your default config or the flags you add when running a script.

In ethers a provider can x while a signer can y

providers can read a smart contract
signers (have access to private key) so can create transactions aka write to blockchain

To use ethers to interact with a contract on a testnet or mainnet, you need to put the script inside scripts folder and run hh run scripts/script.js –network network-name and it already has your ethers object set up.

It seems that in hardhard, getting a instantiating a signer uses the api in the config for the wallet, but getting a provider you need pass in your api info during instantiation.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
58
Q

You can guess which javascript functions will take a long time by

A

asking if this action is probably going to take a long time to complete

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
59
Q

You must use “await” if the function you are calling

A

returns a promise

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
60
Q

To add OpenZeppelin to hardhat, type

A

npm install –save-dev @openzeppelin/contracts

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
61
Q

An abstract class is

A

a base class that you can inherit into a child class but contains functions that are declared but have no body that you will be forced to override them in order to instantiate the child class.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
62
Q

To override a virtual function, type

A

function myFunc() public override(ContractName) {}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
63
Q

A modifier is

A

A function that you add after your visibility keyword that will run before your function.

A modifier can access the parameters passed into the main function by using parentheses.

myModifier(paramName)

You can use multiple modifiers and they will run in sequence.

To create a modifier type

modifier myModifer() {
// do something
_;
}

The underscore in modifiers represents calls the main function or the next modifier in the chain of there is one.

https://youtu.be/RobaQulUzsY

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
64
Q

The basic signature of a function is

A

function functionNams(type paramName, type paramName) visibility modifier modifier returns(type) {}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
65
Q

To return multiple values from one function, type

A

function multiFunc() visibility modifier returns(type, type) {
return(valueOne, valueTwo);
}

And to assign each returned value, type
variableOne, variableTwo := multiFunc()

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
66
Q

For struct, array and mapping types, it is mandatory to

Explicit data location for all variables of struct, array or mapping types is now mandatory. This is also applied to function parameters and return variables.

A

write the explicit data location keyword including for function params and return variables.

uint[] storage myArray;

function myFunc(uint[] memory myArray) visibility modifier returns(uint[] memory) {}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
67
Q

Functions that can be called by external parties must

A

explicitly use calldata as the memory location of the function parameters

function myExternalFunc(string calldata paramOne) visibility modifier {}

68
Q

To call a function from an inherited class that you overwrote in you child class, type

A

super.functionName()

69
Q

If a function has both virtual and override as modifiers it means

A

It is overriding a function with the same signature in a parent contract by using override, and it is also allowing you to override it in you contract by using virtual.

70
Q

The virtual modifier tells the user that

A

the function is allowed to be overridden after you inherit it by using

function sameFunc(type sameParam) visibility override {}

71
Q

An OpenZeppelin hook is

A

simply a function they added to their contracts that runs before other functions that you can override in your child function in order to add functionality into their call sequences.

Rules:
Always re-apply the virtual attribute to the hook. That will allow child contracts to add more functionality to the hook.

Always call the parent’s hook in your override function using super to continue the call sequence. This will make sure all hooks in the inheritance tree are called: contracts like ERC20Pausable rely on this behavior.

contract MyToken is ERC20 {
function _beforeTokenTransfer(address from, address to, uint256 amount)
internal virtual override // Add virtual here!
{
super._beforeTokenTransfer(from, to, amount); // Call parent hook

}
}

72
Q

A token contract is basically

A

a mapping of addresses to balances, plus some methods to add and subtract from those balances.

73
Q

Transferring an nft is basically

A

changing the address mapped to the id of an NFT. Opensea is able to handle transfers by calling contracts that comply with ERC721 standard and asking the user to use metamask in order to sign the transaction to prove ownership.

74
Q

The way dom implements a random list item plucker is

A

uint256 rand = random(string(abi.encodePacked(keyPrefix, toString(tokenId))));
string memory output = sourceArray[rand % sourceArray.length];

75
Q

Opensea is basically

A

a UI for people to use metamask/ethers.js to call functions on contracts that comply with ERC721 which have a tokenId to address mapping.

76
Q

To make a ternary operator in solidity, type

A

1 > 0 ? true : false

77
Q

ERC721 tokens keep a mapping of

A

tokenIds to ownerAddresses and also ownerAddresses and total number of NFTs.

78
Q

The purpose of pinning a file on pinata is to

A

make the IPFS filed you uploaded available even when your local daemon is down.

79
Q

JS cheat sheet javascript

A

The document loaded event doesn’t fire until all images are loaded.

To read from file system synchronously in node, type
const fs = require(“fs”).promises;

fs.readFile(“/…”) etc
Then use all the old names

const fs = require(“fs”);

function range(start, stop, step) {
if (typeof stop == ‘undefined’) {
// one param defined
stop = start;
start = 0;
}

if (typeof step == 'undefined') {
    step = 1;
}

if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
    return [];
}

var result = [];
for (var i = start; step > 0 ? i < stop : i > stop; i += step) {
    result.push(i);
}

return result; };

range(5).forEach(i => {
})

fs.writeFileSync(
contractsDir + “/contract-address.json”,
JSON.stringify(metadataObj)
);

if you are exporting a function, you can still import a dependency from outside of the function
https://stackoverflow.com/questions/27008999/scope-of-dependencies-when-exporting-a-module-in-node-js

To import a file using require, type
const utils = require(“./utils”);

To import one function from a file using require, type
const funcName = require(“./utils”).funcName

To read and write json
JSON.stringify()
JSON.parse()

To get node script argument from command line, type
const args = process.argv.slice(2)
console.log(args[0])

To check if a value is undefined and throw an error, type
if (arg !== undefined) {
}

In js, not providing 2 arguments to .replace()
causes the second argument to become undefined.
Note: Use replaceAll() for replacing all (only in browser, not supported by node)

It seems that if you make a function async, you maybe use await when calling it, not just inside it.

To check if a value is in an array, type
myArray.includes(“value”))

you cannot use await inside
a forEach loop, because each iteration’s execution is asynchronous.

forEach mutates the original array, while map just creates a new object you’ll need to assign.

80
Q

To install a plugin into hardhat the two steps are

A

npm install it
add to hardhat.config.js require(““@nomiclabs/plugin-name””)

81
Q

One way to start a Token contract’s reserves is with

A

all the tokens belonging to the owner and having transfer functions

uint256 public totalSupply = 1000000;
address public owner;
mapping(address => uint256) balances;

constructor() {
The totalSupply is assigned to transaction sender, which is the account
balances[msg.sender] = totalSupply;
owner = msg.sender;
}

82
Q

the ABI is

A

the compiled version of your high level code that the machine code can execute.

83
Q

When you run hh compile, hardhat

A

compiled all your contracts into ABIs and saves the ABIs into the artifacts folder.

84
Q

To assert equality in chai, type

A

expect(true).to.equal(true);

85
Q

The proper structure for mocha tests (like presetting variables) is set out here

A

https://hardhat.org/tutorial/testing-contracts.html#full-coverage

86
Q

The reason to use ERC721Enumerable is

A

it provides a totalSupply method

87
Q

To concatenate 2 strings, type

A

abi.encodePacked(“string”, “string”)

88
Q

Reentrancyguard prevents

A

a contract from calling itself

import “@openzeppelin/contracts/security/ReentrancyGuard.sol”;

Inherit the ReentrancyGuard class

Then add the nonReentrant modifier to a function that is doing something important.

89
Q

OpenZeppelin tells you which methods you need to implement yourself by

A

including them in the IERC file by the same name with no body.

e.g. ERC721, and IERC721

Note: It also injects fully implemented events this way.

90
Q

To convert a BigNumber balance from a smart contract to a readable number, type

A

ethers.BigNumber.from(await contract.totalSupply()).toNumber()
or
ethers.utils.formatEther(await contract.balance)

91
Q

To run scripts in hardhat, type

A

hh run scripts/script.js

92
Q

To deploy my smart contract to an external network, you need to

A

Create an account on alchemy, get your api link and add it to networks in hardhat.config.js

networks: {
rinkeby: {
url: https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_API_KEY},
accounts: [0x${RINKEBY_PRIVATE_KEY}],
}

To get some free eth for the test account
In metamask create a new address in the rinkeby network
Post the address on twitter
Post that into a faucet, which will send you ether
export your private key from metamask and add to hardhat config
https://www.youtube.com/watch?v=Uvphp4aVeDg

Run the deploy script
hh run scripts/deploy.js –network network-name

You can then see it on rinkeby.etherscan.io using the returned address

93
Q

IPFS sheet

A

To run an IPFS daemon, type
ipfs daemon

To download a file hosted in IPFS, type (while daemons on)
ipfs cat /ipfs/QmSgvgwxZGaBLxsYLKtdy3vGZ8uq > ~/Desktop/name.jpg

The target url for files hosted on IPFS is
https://ipfs.io/ipfs/QmXKnygUEzRVVs
or https://gateway.ipfs.io/ipfs/QmXKnygUEzRVVs

And for local it is
http://127.0.0.1:8080/ipfs/09ed8jf2390irdf0reid

To view the local dashboard ui go to localhost:5001/webui

The IPFS Companion chrome extension allows you to open IPFS links in chrome by querying the local daemon running.

This IPFS api wrapper can connect to your local daemon and add files to it
https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-http-client#example

IPFS does not propogate the files you add to it, it just makes it accessible from your node to other nodes. If another node requests it it will storage a copy temporarily.

94
Q

To make a directory path, type

A

const path = require(‘path’);

const directoryPath = path.join(__dirname, ‘../images’);

Note: __dirname is the path to the current script

path.join(“a”, “b”) become “a/b”

95
Q

Remember to make javasrcript

A

very functional

96
Q

ENS is basically

A

There is a smart contract that auctions off names
When someone wins an auction, their name gets added to a mapping (aka registry) of that name to an address of a different smart contract that the auction winner owns (called a resolver)
The resolver contract can be updated to forward transactions to wherever the owner wants (like their metamask wallet)
The resolver contract has a variable called content that can contain an IPFS hash so your ENS name can open that site if you type it into a browser that resolves ENS names (brave) or you can use Name.eth.link as a gateway in other browsers.

https://towardsdatascience.com/decentralizing-your-website-f5bca765f9ed
https://medium.com/xord/ethereum-name-service-ens-how-does-it-work-6d16486451ea

97
Q

You might be able to crypto crowdfund on mirror

A

https://dev.mirror.xyz/llJ_AboiDJwB_ZAFz-CXU7fL2p8v5Wz6MjfluLafewQ

98
Q

For anonymity, I should always upload transactions

A

Using a new public and private key account held by my master key

99
Q

To expand a solidity tuple into variables but skip one you don’t need, type

A

(uint value1, , uint value2)

just add commas but nothing inside

100
Q

CommonJs is a

A

module system that set conventions for how JS imports files. It uses

require(“./path.js”)

and

function funcName1() {)
function funcName2() {)
exports.funcName1 = funcName1
exports.funcName2 = funcName2

or

module.exports = {
funcName: function() {}
}

101
Q

Sequelize sheet

A

How sequelize works at a high level is
You extend their model class with your own class which represents a table and pass in your instance of sequelize on declaration. Then when you call a method on the model and it knows which sequelize object to look for to find the database connection.

when you call sequelize.sync()
sequelize will check if your sqlite db exists and if not it will create it.

To create a new record, type
ModelName.create({column: value}).then()

To get one record type
ModelName.findOne({where: {column: value, column: value}})

You can create a table by
Initializing a model
const { Model, DataTypes } = require(“sequelize”);
const sequelize = require(“../database.js”);
class MyTable extends Model {}

MyTable.init({
column: {type: DataTypes.STRING,},
}, {
sequelize,
modelName: “MyTable”,
});
module.exports = MyTable;

To alter a table, ie drop column/delete table, you must
Create and run a migration using their cli

A common pattern for updating a record
ModelName.findOne({
where: { column: value, column: value} },
}).then(function (obj) {
// if it exists, update
if (obj) {
return obj.update({ column: value });
}
// otherwise seralize and save
console.log(
“There was a transfer on a tokenId: “,
data.address,
tokenId
);

To create a model method type
// Class Method
ModelName.methodName = function (models) {};
// Instance Method
ModelName.prototype.methodName = function () {this.field};

When you change the model definition in the app code and push it to production, there will be a mismatch between the the model representation and the actual database table until you run a migration in production.

for django is used to run heroku run db:migrate, which was effectively an ssh and migrate like you would do locally. Then restart would make it work.

GPT says that if I want to make db migrations live, adding a column is an exception because you can run the migration and the old app will still work fine. If you altering something the app cares about, then pick a low traffic time, and do both quickly.

I wonder if since I cant force users to update mobile apps, i’ll need to keep track of versions and always support old versions of the api.

You keep multiple versions of the API running concurrently and deprecate the older versions when traffic hit low enough levels.

One way of versioning would be to send version info in the HTTP request header, so the URL end point always stays the same.

When making changes that break on older clients, update the major version. You can still make changes to the older version but change the minor version number too. You just have to manage this on both the client and server.

On the side of managing the code, you could set up models for each version, and use inheritance or delegation for falling back to existing code in older versions because you don’t want to keep repeating yourself.

When I develop an API endpoint, it has a well-defined and documented set of parameters and response structure. If that contract changes, I make a new version of the endpoint, with a different URL. Newer versions of the client would use the new endpoint, while older versions would still have the old endpoint.

Changing the behavior an existing endpoint will likely cause problems for clients “out in the wild” that are currently using it.

We went for a simpler approach because we don’t want multiple api versions to share the same code, and we want backward compatibility, so we simply place the codes in different directories.

E.g. api/v1/xxxx
api/v2/xxxx

https://www.youtube.com/watch?v=bWFuEVmRgdk

102
Q

Event logs

A

The problem with listening for events from multiple contracts is you will need to decode the topics yourself.

topics[0] is usually a keccak256 hash of the name of the event signature in the following format: “Transfer(address,address,uint256)”. No variable names, no spaces, no “event”. Note: It includes all parameters, not just indexed parameters (Confirmed in remix)

I verified this by running keccak256(abi.encodePacked(“Transfer(address,address,uint256)”)) and it returned the same value as in my event logs.

I can check etherscan to see the format of the events the contracts I need to track have
https://etherscan.io/address/0xff9c1b15b16263c61d017ee9f65c50e4ae0113d7#events
I confirmed Transfer(address,address,uint256) converts to Loot’s topics[0] signature hash by sending it into encodePacked() and keccak() on remix.

A hex is basically base16 encoding, although ethereum stores values with left padded zeroes.

One hex digit is a nibble, which is half a byte. 64 nibbles = 32 bytes. A 32 bytes hex should have 64 characters.

To turn a number into a hex string, you can type
let n = 1000
n.toString(16)

To turn a hexed number into an integer, type
parseInt(Number(‘0x000000016b9’), ‘hex’)

Note: Javascript uses th 0x at the beginning to represent a hexadecimal string.
Note: Ethereum addresses are really just a number converted to a hex string so thats why they are visible with left padding.

Solidity stores the hex string versions of the parameter values into topics but also left pads it with 0x000 (lots of zeroes), so you need to use a custom decoder to get the real value in real world applications. For quick checks you can just cut out the 0x000.

If one of the topics is a number, it is stored as hex and you can decode it with web3.eth.abi.decodeParameter(‘uint256’, “0x000e52”)

To decode a hex address from an event topic, type
web3.eth.abi.decodeParameter(‘address’, “0x0002b8d5a”)

The data field stores all event fields that are not indexed in a hex string.

Note, all topics and the data field are stored

Parameters that are not indexed do not get a topics array item.

If the data field is only ‘0x’ it means all the parameters were indexed.

This guy implies even non indexed parameters are included in the event signsature hash
https://ethereum.stackexchange.com/questions/12950/what-are-solidity-events-and-how-they-are-related-to-topics-and-logs

I was getting errors because some contracts do not index the tokenId so I was parsing outside the topics array length of 2 in that case instead of 3 because unindexed events go into the data field.

103
Q

Cryptographic hash function sheet

A

The main cryptographic hash function in solidity is keccak256

keccak256() takes in an arbitrary size bytes object and returns a bytes32 object which is restricted size.

Cryptographic hash functions in general take in an arbitrary size bytes object and return an encoded bytes object of restricted size. The output is deterministic (same input always provide the same output) and you cannot know the input by looking at the output.

The input to keccak256() must be of type bytes, so to turn your arbitrary data types into a concatenated bytes object, type
abi.encodePacked(“string”, unint(1), address(efcr4))

To verify you have the correct input for a hash, you need to run the same hash function on the input and see if the outputs are the same

https://www.youtube.com/watch?v=rxZR3ITZlzE

104
Q

You only declare the memory location in arguments of function definition if they are of types

A

string, bytes, array, struct, mapping

broadly variable size?

105
Q

You only declare the memory location in arguments of function definition if they are of types

A

string, array, struct, mapping

106
Q

0x is

A

a prefix added to numbers to specify they are a hex number aka base 16

107
Q

A serializer is reversible translator, a formatter is not

A

.

108
Q

Flask sheet

A

To create the tables defined in SQLAlchecmy, type
from main import db
db.create_all() into the interpreter

To add an object to the database from the interpreter, type
db.session.add(obj)
db.session.commit()

If you add an object to db.session that is not suitable and want to remove all items, type
db.session.remove()

To get a record, type
ModelName.query.filter_by(column_name=”value”).first()
https://flask-sqlalchemy.palletsprojects.com/en/2.x/queries/#querying-records

To make a foreign key, type
wallet_id = db.Column(db.Integer, db.ForeignKey(‘wallet.id’), nullable=False)
wallet = db.relationship(‘Wallet’, backref=db.backref(‘nfts’, lazy=True))

Gotchas for deploying flask with postgres to heroku:
You need pyscopg2 in the requirements, and you need to change heroku’s DATABASE_URL to start with postgresql instead of postgres.
https://stackoverflow.com/questions/58401435/how-to-use-pip3-install-psycopg2
https://stackoverflow.com/questions/35061914/how-to-change-database-url-for-a-heroku-application

After you call db.commit(), your model will have the id property set. Example:
db.session.add(user)
db.session.commit()
print user.id (has id)

To make database models in flask, type
from flask_sqlalchemy import SQLAlchemy

app.config[‘SQLALCHEMY_DATABASE_URI’] = os.environ.get(‘DATABASE_URL’, ‘sqlite:///demo.db’)
db = SQLAlchemy(app)

class Wallet(db.Model):
id = db.Column(db.Integer, primary_key=True)
address = db.Column(db.String(200), unique=True, nullable=False)
def __repr__(self):
return ‘’ % self.address

class Nft(db.Model):
id = db.Column(db.Integer, primary_key=True)
token_id = db.Column(db.Integer, nullable=False)
symbol = db.Column(db.String(200), nullable=False)
name = db.Column(db.String(200), nullable=False)
description = db.Column(db.Text, nullable=False)
image_uri = db.Column(db.String(200), nullable=False)
wallet_id = db.Column(db.Integer, db.ForeignKey(‘wallet.id’), nullable=False)
wallet = db.relationship(‘Wallet’, backref=db.backref(‘nfts’, lazy=True))
def __repr__(self):
return ‘’ % self.symbol

109
Q

Styling wise, remember to

A

put all the variable declarations at the top and avoid adding variables you only use once.

110
Q

You cannot count the number of elements inside a

A

mapping

111
Q

To create a struct and assign values to it, type

A

struct Person {
uint height; // or assign here with =
bool alive;
address friend;
}

Person myPerson = Person(10, false, 0xdjer0do3);

or

struct Drop {
    uint supply;
    address[] valuedCollections;
    string baseUri;
    address deployer;
    address minterProxy;
    mapping (address => uint) usedNfts;
}

mapping (uint => Drop) drops;

Drop storage drop = drops[currentDropId];

    Drop storage drop = drops[currentDropId];
    drop.supply = supply;
    drop.valuedCollections = valuedCollections;
    drop.baseUri = baseUri;
    drop.deployer = msg.sender;
    drop.minterProxy = minterProxy;
112
Q

To make a contract pausable, add

A

bool _paused = false;

function _pause()
function _unPause()
function paused()

function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {
    super._beforeTokenTransfer(from, to, tokenId);

    require(!paused(), "ERC721Pausable: token transfer while paused");
}
113
Q

bootstrap

A

to make a button into a btn-block in bootstrap5 use
-div class=”d-grid”>
-button type=”submit” class=”btn btn-primary btn-lg”>Submit
-/div>

114
Q

The smallest subdivision of ether is

A

wei

like a penny

115
Q

web3.py sheet

A

To call a contract function, type
from web3 import Web3
infura_url = “https://mainnet.infura.io/v3/34rf34e”
web3 = Web3(Web3.HTTPProvider(infura_url))
abi = json.loads(‘abi’)
address = ‘0xd26114cd6EE289AccF82350c8d8487fedB8A0C07’
contract = web3.eth.contract(address=address, abi=abi)
totalSupply = contract.functions.totalSupply().call()
balance = contract.functions.balanceOf(‘0xd207’).call()

To convert Wei to ether, type
web3.fromWei(balance, ‘ether’))

Seems like if I want to use web3.py with metamask, I need to use web3.py to create the transaction, then send that to the client to ask metamask to sign it, and then send the signed version to the server to run the python function.

116
Q

Read only functions do not cost any gas because they

A

just query your local node, rather than ask the network to change something.

117
Q

In general when you want to use a dictionary with 3 values, use a

A

struct

118
Q

Dynamic arrays can only use .push() is they are

A

stored in storage

119
Q

To make a loop, type

A

Nft[] memory result;

    for (uint i = 0; i < nfts.length; i++) {
        if (verifiedNftOwner(nfts[i].contractAddress, msg.sender, nfts[i].tokenId)) {
            result.push(nfts[i]);
        }
    }
120
Q

Develop in remix

A

test in hardhat

121
Q

If you look up a non existent key in a mapping (string => uint) you will get back

If you look up a non existent key in a mapping (string => bool) you will get back

A

0, false

122
Q

To send money between contracts using interface, type

A

This is how you handle amount sending between contracts via interface:

ContractA.sol:

pragma solidity ^0.5.11;

contract A {
uint256 public lastFundSentToContract = 0;

function updateLastFundSentToContract () public payable {
    lastFundSentToContract = msg.value;
}

function getContractBalance() public view returns(uint256) {
    return address(this).balance;
} } ContractB.sol:

pragma solidity ^0.5.11;

contract B {
A a_contract_instance;
constructor(address _a_contract_address) public {
a_contract_instance = A(_a_contract_address);
}

function callToContractA() public payable {
    a_contract_instance.updateLastFundSentToContract.value(msg.value)();
}

function getContractBalance() public view returns(uint256) {
    return address(this).balance;
} }

interface A {
function updateLastFundSentToContract () external payable;
}

But what about arguments?
address.function{value:msg.value}(arg1, arg2, arg3)

https://ethereum.stackexchange.com/questions/9705/how-can-you-call-a-payable-function-in-another-contract-with-arguments-and-send

123
Q

A nonce is basically a value that makes sure

A

you dont duplicate a transaction

124
Q

If an error happens in a function you are calling in a remote contract using an interface

A

the error will cause an error on your function too and propagate back to the user.

125
Q

In metamask, every new account you create gets

A

a different private key

126
Q

My big mistake when making my ERC20 token was

A

I didnt use it as an inheritance, I just deployed what they already had without any of my customization.

127
Q

The value of giving names to return values is

A

The name is a clue on what information should go there.

It does not require one to initialize a given variable since it gets initialized automatically with the default/zero value.

You don’t have to explicitly return it.
https://ethereum.stackexchange.com/questions/34046/what-is-the-purpose-of-giving-name-to-return-variables-in-function-declaration

128
Q

Since functions that create transactions take time to verify, they

A

don’t return a value, they return a transaction. You will need to listen to when that transaction is verified and then call a different function to get your value.

129
Q

To create an array that does not require a storage location

A

it must be fixed length, and you must assign values like below

uint[] memory staticArray = new uint;
for (uint i = 0; i < myArray.length; i++) {
staticArray[i] = value;
}

https://www.youtube.com/watch?v=QGjshWJjPPI

130
Q

This guy says you can return a struct from solidity

A

https://www.youtube.com/watch?v=QGjshWJjPPI

131
Q

To throw an error in solidity, call

A

revert()

132
Q

a fallback function can be defined

A

fallback() external {

}

or function() {
}

133
Q

To define a fallback function, type

A

fallback() external {

}

The old way is:
or function() external {
}

134
Q

The only difference between a monetary transaction and a smart contract transaction is

A

the smart contract transaction will populate the “data:” field with the concatenated function id and parameter values.

To get the function id, you keccak256 has the ASCII form of the signature ie. myFunc(type,type) and the only use the first 8 characters in that hash so 0x and then 8 characters.

The length of the data parameter with one function argument is always 74 characters (including 0x).

Static parameters are encoded in a fairly straightforward manner–they are converted to their hex representation and then concatenated onto the input data hex string.

You can encode a parameter using this function https://web3js.readthedocs.io/en/v1.2.0/web3-eth-abi.html#encodeparameter

This explains how the dynamic parameters are handled. Essentially the location where it is supposed to be in the sequence is replaced by an index of it’s new location, then it gets added to the end of the param array but that value is the character length of the dynamic value, and then the real value comes after that.
https://ethereum.stackexchange.com/questions/68558/encoded-input-params

135
Q

To verify code on etherscan using hardhat, type

A

npx hardhat clean
npx hardhat verify –network mainnet deployedAddress “Constructor argument 1”
https://hardhat.org/plugins/nomiclabs-hardhat-etherscan.html

This can look like it failed in CLI when it actually worked

Note:
I was failing to verify my file with 2 contracts in it because my interfaces were in between my contracts instead of on top of them (in same file?)

136
Q

To get someone to spend ERC20 tokens to use a smart contract

A

Make them call approve with your smart contract address so it has an allowance.

Then call transferFrom with the address you are trying to take from and the address you are trying to move funds to.
Note: The msg.sender must be the account with an allowance from the approve call.

137
Q

To create a contract that creates another contract on a unique address, type

A

contract A {
address owner;
string name;
string symbol;

constructor(address _owner, string memory _name, string memory _symbol) {
  owner = _owner;
  name = _name;
  symbol = _symbol;
}
function getOwner() public view returns(address) {
    return owner;
} }

contract AFactory {
mapping (address => address[]) owners;
event DeployMinter(address owner, string name, string symbol);
function createObject(address owner, string memory name, string memory symbol) public {
owners[owner].push(address(new A(owner, name, symbol)));
emit DeployMinter(owner, name, symbol);
}
function getAddresses(address owner) public view returns (address[] memory) {
return owners[owner];
}
}

Note:
Since this function creates a transaction, there is no return value returned on etherscan.
The only way I know to verify this type of child contract is to run the verify function from hardhat of the same file that creates it.

I also failed to verify for a while because I stupidly forgot that I need to pass in the same constructor parameters I used in contract creator function to the verification in order for it to work.

Note: If I deploy a contract thats been optimized, it seems the contracts that it deploys will also be optimized.

138
Q

To import a local solidity file, type

A

import “./MinterFactoryTest.sol”;

139
Q

wBTC is

A

an erc20 token that is holding btc in reserve with 1:1. This requires there being a party storing that btc since the networks cant talk to each other.

If someone buys a wBTC it should give them the ability to
The wBTC price should be accurate because the market will not want to overpay and will try to underpay.

140
Q

block.timestamp in solidity return

A

an integer of number of seconds since the “Unix epoch”

141
Q

The default value for an address is a mapping is

A

address(0) or 0x0000000000000000000000000000000000000000

142
Q

In solidity, as in java, the == operator does not compare the literals of two strings. You should use

A

the StringUtils contract instead or
keccak256(bytes(“string”)) == keccak256(bytes(“signed”)).

143
Q

If I have a struct as the value in a mapping, i can rely on it being a defaul value and instantiate it like

A

Drop storage drop
= allDrop[availableDropId];

144
Q

A good explanation of the main encryption schemes

A

Encoding: Some rules that convert it to a new format
Symmetric: One cipher key to encrypt and use same to decrypt
Asymmetric: One public key to encrypt, and a different one to decrypt
One way hash function: Cannot be decrypted
For ethereum : The message is encrypted by the private key and the public key is recovered from the hash by knowing the message contents

https://www.youtube.com/watch?v=lnKPoWZnNNM

145
Q

React sheet

A

Slices basically export your reducer for the rootReducer and your actions.

To update the state, the reducers in slices can either modify the state variable without returning anything, or return the full state like the old way, but not both modify and use return.

To conditionally render a component, type
{true
?
:
}

When you create a slice what you are really doing is
creating a reducer you can plug into rootReducer and creating action creators for the synchronous reducers the the reducers field (not the async ones)

In slices
Async action creators are handled in extraReducers
Regular action creators are handled in reducers

action creators created by createAsyncThunk automatically get 2 properties, thunkName.pending and thunkName.fulfilled, and these are used as action types so the reducer handles both

every function call has to be dispatched.
You pass an action creator to a dispatch call. That action creator is either simple or asynchronous. All the action happens in the action creator.

To run a function on mount just once type
useEffect(() => {
});

To create a url with a param, type
import { useParams } from ‘react-router-dom’
function Page() {
const { param } = useParams();

-Route path=”/drop/:dropUrl” element={} />

146
Q

When setting prices in solidity, no unit after the number is assumed to be

A

wei

assert(1 wei == 1);
assert(1 gwei == 1e9);
assert(1 ether == 1e18);

147
Q

To multiply two BigNumbers, use

A

.mul() not *

148
Q

In js, the replacement for a list comprehension is

A

.filter() which returns true or false to remove items, and .map() which returns a mutated version of each item

149
Q

Metamask lets you request that a user add

A

a new network, and even switch to that network after they added it.

150
Q

The purpose of -meta name=”theme-color” content=”#4285f4”> is to

A

recommend the color of the browser’s frame

eg: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name/theme-color

151
Q

Having a manifest.json is required by Chrome to show the

A

Add to Home Screen prompt. It basically gives phones the assets and metadata needed in order to add your app to home screen.

https://web.dev/add-manifest/

152
Q

A rollup is basically

A

a smart contract that holds a merkle root of a large number of transactions that were hashed together off chain. The transaction that updates the merkle root with a new batch takes all the state data as calldata, so the data is saved publicly in the the transaction, but not as variables in the contract.

An optimistic rollup allows anyone to update the state but someone else can submit a fraud proof to revert a transaction.

1mb is the limit for calldata, and its 1m characters.

153
Q

If a smart contract does not define a receive function or a payable fallback function, it

A

cannot receive eth

154
Q

If you send a read transaction and it reverts, you still

A

pay gas, but left over gas gets refunded

155
Q

The different between revert and require is

A

revert is better when you need multiple lines of logic before the revert. Require is just one line.

156
Q

To give an element padding using bootstrap, type

A

p-2

157
Q

To use css modules in react, just

A

rename the css file to name.module.css

In the file
import { styles } from ‘./name.module.css’

className={styles.class}

158
Q

Sending ether to a smart contract triggers its

A

fallback function

159
Q

The nonce allows you to be sure that

A

two transactions from the same address will be mined in the right order

160
Q

To checkout someone else’s git branch that only exists in remote, type

A

git switch branch_name

161
Q

Opensea Sheet

A

In order for a metadata url to be imported into opensea, it needs to have a url ending in .json

162
Q

It seems you cannot upload private abis to etherscan

A

on rinkeby, only mainnet

163
Q

Passing a 1 with not unit into ethers as an eth value represents

A

wei the smallest unit

164
Q

Data

A

ETL stands for
extract, transform, load

Basically getting data from multiple places into one place converted into the format you want

Spark is used for
processing and operating on large data

Kafka is a
pub/sub messaging system

A data pipeline is
the tools data travels through to get from one system to another

165
Q

A preflight request tells the browser

A

which domains are whitelisted on the server, so the browser can enforce preventing the request if its not whitelisted.

166
Q

Zero knowledge proofs

A

A zk proof allows you to prove that a specific computation ran on values (which can stay private) and yielded a particular return value.

A prover is the function that
runs your computation and generates a proof that it ran successfully.

A verifier is a function that
checks if the proof is legit.

A witness is
a type of proof.

An MMO that uses zk proofs
https://github.com/darkforest-eth/darkforest-v0.3

A game article
https://weijiek.medium.com/how-i-learned-zk-snarks-from-scratch-177a01c5514e

A great video using circom
https://www.youtube.com/watch?v=Oaub9QwwgCA

167
Q

The way ethereum addresses are generated is

A

1) Generate a random private key
2) Derive a public key from it using ECDSA
3) Derive an address by keccak hashing that and keeping the last 40 characters

https://ethereum.stackexchange.com/questions/3542/how-are-ethereum-addresses-generated