6 min read

Hands-On Smart Contract Development with Solidity & Ethereum - Notes

The following post contains some information about the wonderful book I am currently reading/working through:

Hands-On Smart Contract Development with Solidity and Ethereum
Ready to dive into smart contract development for the blockchain? With this practical guide, experienced engineers and beginners alike will quickly learn the entire process for building smart contracts for … - Selection from Hands-On Smart Contract Development with Solidity and Ethereum [Book]

There were occasional hiccups as I worked through the examples. Namely, some packages required some tweaks to get the examples working.

It's a great book for some practical training on the topic. I knew a little bit coming in, so I have a hard time assessing the quantity of technical information provided in the book.

I'll continue updating this post as I work through it. I'm currently through the first portion.

UPDATE: 29 Dec 2021 - added Chapter 7: FundraiserFactory notes

UPDATE: 31 Dec 2021 - started adding Chapter 9: Connecting the UI to Our Contracts notes (covers the first step - unboxing and starting the client)

UPDATE: 31 Dec 2021 (2) - finished Chapter 9 (added fix for setGreeting)


Chapter 5

Two items are relevant when you start working with the client project:

  1. The client must be run with node version 12 (some of the dependencies will not work on 14).
  2. before the client project start (npm run start) will work, perform an NPM install in the client project: npm install --save-dev @babel/core @babel/preset-env
  3. Copy the client UI project for Greeter from the chapter5 folder, not the chapter9 folder. The chapter9 folder contains the fundraiser contracts and the application will not load correctly.

With the second item, the client will start, but there will be a webpack error when the page loads.


Chapter 6

Some things have changed in the various technologies since the book was published.

  1. [Page 106] where it says to npm install openzeppelin-solidity --save , the line instead needs to be npm install @openzeppelin/contracts --save. The version of this at the time of writing is 4.3.3. The import must also be changed to import "@openzeppelin/contracts/access/Ownable.sol"
  2. The solidity version must be updated to reflect a newer version. This is done in truffle-config.js. The error will arise when running truffle test after importing the adding the is Ownable
  3. The function call for transferring the ownership has been changed as well - it is now transferOwnership(_custodian) .
  4. The Donation structure constructor will not with the conversionFactor member initially (tests do not set it). To rectify, either remove the conversionFactor temporarily or add a dummy value to the initializer.
  5. Switching to Solidity version (0.8) does not require SafeMath because overflow checks were implemented by default. That also means the using SafeMath uint256 statement is not required. The add() function to increment totalDonations is also not required (replace it with a normal addition using the + operator).
  6. When adding the fallback function: Solidity 0.8 has updated the way to declare the fallback function. Therefore, it needs to be declared as fallback() external payable instead of function() external payable. Of course, the safe math provision is not required either (per the previous item).
// Ommitted...

module.exports {
	// Ommitted...
    compilers: {
    	solc: {
        	version: "^0.8",    // Fetch exact version from solc-bin (default: truffle's version)
        }
    }
};
truffle-config.js - Updating the solc version

Chapter 7

NOTE: I got this one working, but I'm not entirely certain that this solved it. The code in the book is a bit behind the most current web3 information. I'll update the post when I determine the exact information.

NOTE: The UI does not seem to function correctly - additional investigation required, but for now I'm going to keep working on the next chapter.

After copying the project, I started to face several V8 errors (related to node-gyp building the libraries). For the less familiar - node-gyp is used to compile native code.

  1. The first error as a sample is shown in the code snippet below when copying the client project and running npm install . To fix this one, I used the 1.2.4 version of web3 with npm install --save web3@1.2.4 - I also made sure that I started with a fresh Ganache workspace.
websocket@github:web3-js/WebSocket-Node#b134a75541b5db59668df81c03e926cd5f325077 install C:\projects\blockchain\fundraiser\client\node_modules\websocket
> (node-gyp rebuild 2> builderror.log) || (exit 0)


C:\projects\blockchain\fundraiser\client\node_modules\websocket>if not defined npm_config_node_gyp (node "C:\tools\node12\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild )  else (node "C:\tools\node12\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" rebuild )
Building the projects in this solution one at a time. To enable parallel build, please add the "-m" switch.
  bufferutil.cc
  win_delay_load_hook.cc
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(34,1): error C2660: 'v8::FunctionTemplate::GetFunction': function does not take 0 arguments [C:\projects\blockchain\fundraiser\client\node_mo
dules\websocket\build\bufferutil.vcxproj]
C:\Users\mgrab\AppData\Local\node-gyp\Cache\12.22.7\include\node\v8.h(6126,46): message : see declaration of 'v8::FunctionTemplate::GetFunction' (compiling source file ..\src\bufferutil.cc) [C:\projects\blockchain\fundraise
r\client\node_modules\websocket\build\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(34,1): error C2661: 'Nan::Set': no overloaded function takes 2 arguments [C:\projects\blockchain\fundraiser\client\node_modules\websocket\bui
ld\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(50,1): error C2661: 'v8::Value::ToObject': no overloaded function takes 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\we
bsocket\build\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(57,1): error C2661: 'v8::Value::ToObject': no overloaded function takes 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\we
bsocket\build\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(68,1): error C2661: 'v8::Value::ToObject': no overloaded function takes 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\we
bsocket\build\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(70,1): error C2661: 'v8::Value::ToObject': no overloaded function takes 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\we
bsocket\build\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(89,1): error C2661: 'v8::Value::ToObject': no overloaded function takes 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\we
bsocket\build\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(90,1): error C2661: 'v8::Value::ToObject': no overloaded function takes 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\we
bsocket\build\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(92,1): error C2661: 'v8::Value::ToObject': no overloaded function takes 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\we
bsocket\build\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(93,1): error C2660: 'v8::Value::Int32Value': function does not take 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\websoc
ket\build\bufferutil.vcxproj]
C:\Users\mgrab\AppData\Local\node-gyp\Cache\12.22.7\include\node\v8.h(2709,40): message : see declaration of 'v8::Value::Int32Value' (compiling source file ..\src\bufferutil.cc) [C:\projects\blockchain\fundraiser\client\nod
e_modules\websocket\build\bufferutil.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\bufferutil.cc(94,1): error C2660: 'v8::Value::Int32Value': function does not take 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\websoc
ket\build\bufferutil.vcxproj]
C:\Users\mgrab\AppData\Local\node-gyp\Cache\12.22.7\include\node\v8.h(2709,40): message : see declaration of 'v8::Value::Int32Value' (compiling source file ..\src\bufferutil.cc) [C:\projects\blockchain\fundraiser\client\nod
e_modules\websocket\build\bufferutil.vcxproj]
  validation.cc
  win_delay_load_hook.cc
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\validation.cc(114,1): error C2660: 'v8::FunctionTemplate::GetFunction': function does not take 0 arguments [C:\projects\blockchain\fundraiser\client\node_m
odules\websocket\build\validation.vcxproj]
C:\Users\mgrab\AppData\Local\node-gyp\Cache\12.22.7\include\node\v8.h(6126,46): message : see declaration of 'v8::FunctionTemplate::GetFunction' (compiling source file ..\src\validation.cc) [C:\projects\blockchain\fundraise
r\client\node_modules\websocket\build\validation.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\validation.cc(114,1): error C2661: 'Nan::Set': no overloaded function takes 2 arguments [C:\projects\blockchain\fundraiser\client\node_modules\websocket\bu
ild\validation.vcxproj]
C:\projects\blockchain\fundraiser\client\node_modules\websocket\src\validation.cc(133,1): error C2661: 'v8::Value::ToObject': no overloaded function takes 0 arguments [C:\projects\blockchain\fundraiser\client\node_modules\w
ebsocket\build\validation.vcxproj]
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
V8 Errors running npm install

Chapter 9

  1. Building the UI for the basic projects does not work. Use node12 to unbox the package. To overcome the errors on the web3 install with the client project, update the version: npm i --save web3@1.3. At the time of writing, 1.3.6 was installed and when running via npm run start , the MetaMask wallet application opened and accepted the contract. The storage demo also worked.
  2. The last step (the formSubmitHandler implementation to set the greeting on-chain) omits sending the transaction. The code line here should be const updatedGreeting = await contracts.methods.setGreeting(greeting).send({from: accounts[0]});

Footnotes:

  1. Ultimately, naming the article "Errata" would be disingenuous - the book is a little older now, and to expect technology to never change is illogical. It didn't take much to