Applying Blockchain to On-Time Payment Collection for Small Business Owners

Building a smart contract on Ethereum with web3.js, Node.js, and Ganache

Colin Kraczkowsky
The Startup

--

Owning and running a small business can be one of the most satisfying and liberating careers out there. Unfortunately, in many countries including the United States, small business ownership is a challenge. According to data from the Bureau of Labor Statistics within the United States Department of Labor, 20% of small businesses fail in their first year, 50% fail in their fifth year, and 70% fail in their tenth year. One of the most common reasons why small businesses fail, according to Investopedia, is inadequate business planning and primarily struggles with cash flow. In fact, a survey from 2019 showed 61% of small businesses around the world reported having this issue. One primary cause of cash flow issues is the small business owner’s inability to collect payment when it is due.

In 2018, Intuit QuickBooks ran a survey of 500 self-employed workers and 400 small business owners. Respondents to that survey reported that collecting payment quickly and accurately is the #1 challenge for self-employed workers and small business owners. Late payments cause a series of challenges for small business owners: paying their vendors/suppliers, paying back pending loans, and paying their employees or even themselves. Looking into the data, that same QuickBooks survey revealed that 30% of respondents said that late payments have prevented them from paying their own bills, 22% said it has prevented them from expanding their businesses, and 5% have had to sell their own homes because of a late payment.

How bad is this issue? According to the QuickBooks survey, only 41% of self-employed workers and small business owners have never received late payments. Of the remaining 59% of respondents, 8% of self-employed workers and 4% of business owners report that over half of payments are late. How late are these payments? The survey reveals that 41% report receipt of payment one to three weeks after the due date and 58% report waiting up to a month or more. Worse yet, many of these businesses have provided services for which they will never get paid. According to the survey, 53% of self-employed workers and 64% of small business owners report at least one client per year who flat out refuses to pay, and 14% of self-employed workers and 10% of business owners report at least one client every week who refuses to pay.

Applying blockchain to this problem

Imagine a world where late payments don’t exist because payment is written and executed via the agreement between the small business and its client! This is being made possible by a core technology of the Ethereum blockchain: smart contracts. A smart contract, as described by the National Institute of Standards and Technology agency of the United States Department of Commerce and the Ethereum Foundation, is a “collection of code and data (sometimes referred to as functions and state) that is deployed using cryptographically signed transactions on the blockchain network”. Let’s unpack this definition. The first key point is “collection of code and data” — this means that we can use smart contracts to write business logic, store the output of that logic, and manipulate that output to do what we need with it. The next key point is “deployed using cryptographically signed transactions” — this ensures that all interactions with this smart contract are secure through application of security technologies like asymmetric cryptography and encryption to everything from the account holder’s information, to the interactions, to the smart contract itself so that not even the network doing the processing can access the underlying data. The final key point is “on the blockchain network” — this means that all interactions with this smart contract are persisted and immutable because the execution is controlled and audited by a network of independent computers rather than by centralized authorities that can control and manipulate activities on the network.

Let’s take a look at how we could build a solution that enables small businesses to collect payment on time by writing a smart contract in Solidity, an object-oriented, high-level language for implementing smart contracts and designed to target the Ethereum Virtual Machine (EVM), and executing the contract using the web3.js library, a popular JavaScript library that provides an API to interact with an Ethereum blockchain.

To follow along, you can find the source code on my GitHub.

Building a solution using smart contracts and the Ethereum blockchain

Conceptually, we break the problem down into two parties: the small business that is providing the service and the client who is consuming the service. Common business practice today is for the service provider to outline the payment terms in an invoice which then gets sent to the service consumer. The expectation is that the service consumer will pay the amount stated in the invoice at the time stated in the invoice. As we discussed above, this is often not the case. In the solution that we will build, we write the invoice into a smart contract that securely captures and executes the payment terms according to the logic that we code.

Our simplified example begins with a fictional small business owner who creates an instance of our smart contract that includes the agreed upon payment terms with their fictional client.

First, we set up a project to hold our smart contract.

$ mkdir smb-smart-contract-ethereum
$ cd smb-smart-contract-ethereum
$ echo “{ \”name\”: \”smb-smart-contract-ethereum\”, \”version\”: \”1.0.0\”, \”description\”: \”A decentralized application (dapp) containing a smart contract deployed to an in-memory blockchain.\” }” >> package.json
$ touch SmartInvoice.sol

Within the SmartInvoice.sol file, we write the contents of our smart contract.

contract SmartInvoice {
uint public dueDate;
uint public invoiceAmount;
address serviceProvider;
constructor(uint _invoiceAmount) public {
dueDate = block.timestamp + 200;
invoiceAmount = _invoiceAmount;
serviceProvider = msg.sender;
}
...
}

In the Solidity source code of our smart contract, we first create an instance of a contract and name it SmartInvoice accordingly. Conceptually, a contract in Solidity is similar to a class in object-oriented languages like JavaScript. They persist data via state variables and modify these variables via functions. Within this contract we create all of the state variables that make up the content of the agreement between the small business and the client as well as functions that will execute the terms of this agreement.

Let’s define those state variables and functions now. When calling functions, the Solidity language describes two kinds of calls: internal calls known as “message calls” that do not create a call to the EVM and external calls that do. Because of this, Solidity defines four types of visibilities that can be applied to functions and state variables: external, public, internal or private. A state variable with public visibility is part of the contract interface and can be either called internally or via message calls. In addition, Solidity generates an automatic getter function for public state variables. Since we want both parties to be able to see the invoice’s due date and the amount that is due, we define two state variables, dueDate and invoiceAmount, and give them a visibility of public so that an interface for this smart contract could easily get these variables. We define these variables using the uint type indicating that the expected input will be an integer. In addition to dueDate and invoiceAmount, we also define a third state variable, serviceProvider, that will hold the address of the small business on the blockchain. Note first that we do not explicitly define a visibility for this variable. That is because Solidity assigns state variables a visibility of internal by default. By not assigning our serviceProvider variable a visibility means that it can only be accessed from within the current smart contract or any smart contracts derived from it and will not be explicitly available to an interface for this smart contract. Note second that we define our serviceProvider variable as an address type. An address variable holds a 20 byte value, which just so happens to be the size of an address on the Ethereum blockchain, and has special “members” which can be thought of as functions and properties specific to variables of this type. For example, we can use serviceProvider.balance in our contract to access the balance of the account at this address where balance is a member property.

Now that we have defined the state variables that we want available throughout our smart contract, we call the constructor method of the contract to initialize these variables. The constructor function is executed only once at the time when the smart contract is created. Since the small business will most likely have different invoice amounts per client, we tell the constructor to expect the _invoiceAmount parameter upon construction of the contract.

Making payments within smart contracts

Back to the business process in our simplified example of invoicing for a small business. Once the smart contract has been created with the invoice’s due date and the amount that is due, the small business owner can make it available to their client to sign and initiate payment. The benefit of the blockchain is that payments can be stored within the contract itself rather than in either party’s bank account: sort of like a digital escrow service. This enables all parties to see where the payment is throughout the delivery of the service. Since the contract is on the blockchain, it is secured by the cryptography and hashing capabilities of the platform.

Let’s take a look at how making payments can be done using Solidity.

contract SmartInvoice {
...
fallback () payable external {
require(
msg.value == invoiceAmount,
'Payment should be the invoiced amount.'
);
}

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

To achieve this in Solidity, we define a function to collect the payment from the client and store it in the smart contract. We achieve this with the first function in the code snippet above. We will go into the meaning of the fallback keyword later in this blog, because I first want to bring your attention to the payable keyword. This keyword is known as a “modifier” in Solidity. Modifiers can be used to easily change the behavior of functions. In our example, we are using the payable modifier to indicate that this function is able to receive Ether, the form of payment that we will use for this smart contract. In addition, we give this function external visibility so that it can be called from other smart contracts and via transactions. That means that when we send a transaction containing Ether to our smart contract it will be this function that accepts it. Within the definition of this function, we can also perform operations. The operation that we perform is a basic check that the payment issued by the small business’ client is the same as the amount that is due. To achieve this, we use the require function, a.k.a. a “convenience function”, provided by Solidity which checks for conditions and throws an exception if the condition is not met. In our example, we check that the value sent in the transaction is equivalent to the invoiceAmount set when the contract was instantiated. If this condition resolves to true then our function is executed, but if it resolves to false then the transaction is reverted and the error along with a custom message that we defined is sent in the response. In this case no Ether is sent to the smart contract, and the executing account is only charged for the processing of the transaction as the transaction still adds a new block in the blockchain with a note that the transaction was reverted.

We also define the getContractBalance function which is a custom getter function enabling all parties to see the current balance held in the contract. We define this function using the view keyword which restricts the function from modifying the state of the contract, i.e. we can call this function without paying for the gas required by the Ethereum network to process its execution. We also define that getContractBalance will return some data of the uint type. In the body of the function, we code a simple return statement using address(this) to get a reference to the address of this instance of the contract which, recall from the Building a solution using smart contracts and the Ethereum blockchain section above, gives us access to the balance member which we use to return the balance of the contract.

Great! Now our fictional small business owner can establish an invoice amount and a due date for payment within the smart contract, our fictional client can securely pay the invoiced amount to the contract, and both parties can observe the contract’s balance. The final step is to enable the small business to receive the payment.

Receiving payments within smart contracts

Back to the business process in our simplified example of invoicing for a small business. Once the client has paid the invoiced amount, the small business owner can withdraw the payment from the smart contract. The benefit of the smart contract is that we can write logic into it to ensure that certain requirements are met for the transaction to take place. For example, we should ensure that the payment can only be withdrawn by certain accounts. In addition, our smart contract should allow the withdrawal to take place only after a specified amount of time has elapsed.

Let’s take a look at how receiving payments can be done using Solidity.

contract SmartInvoice {
...
function withdraw() public {
require(
msg.sender == serviceProvider,
'Only the service provider can withdraw the payment.'
);

require(
block.timestamp > dueDate,
'Due date has not been reached.'
);
msg.sender.transfer(address(this).balance);
}
...
}

Like we already did in the Making payments within smart contracts section above, we define a new function, name it withdraw, and give it public visibility so that it can receive messages sent from an Ethereum API which we will leverage later in this blog. Within the body of our withdraw function, we use the familiar require function to establish the conditions that we require for this transaction to take place. The first condition requires that the party attempting to withdraw payment from the contract must be the provider of the service. We can determine who the attempting party is using the msg variable provided by Solidity which is a special global variable that contains properties which allow access to the blockchain. One of these properties is sender which references the address from which the function was called. Recall from the Building a solution using smart contracts and the Ethereum blockchain section above that we have stored the address of the small business owner’s account so it is just a matter of using Solidity’s equality operator to verify that the address of the executor of the function and that account address are the same. If they are not then the transaction is reverted and the EVM will throw our custom error message.

If this first condition is met, we move into our next condition. This condition requires that the party attempting to withdraw the payment should only be able to do so after the agreed upon due date. Executing this function will attempt to change the state of the contract, i.e. transferring funds from the smart contract to the receiving account, and will therefore create a transaction that will be included in a new block on the blockchain. This block has a timestamp that we can access via block.timestamp which will reference the timestamp of the block that this transaction was included in as seconds since the Unix epoch, i.e. the time elapsed since 00:00:00 UTC January 1, 1970. We can then compare this timestamp to the due date that we established in the Building a solution using smart contracts and the Ethereum blockchain section above and stored in the dueDate variable. If the timestamp of the block containing the transaction is less than the due date then the transaction is reverted and the EVM will throw our custom error message.

If all above conditions are met, we can finally move into the purpose of our withdraw function. Once again we use msg.sender to retrieve the address from which the function was called. We then use the transfer method provided by Solidity to send Ether, in units of wei, to this address. The amount sent in this case is the balance of the smart contract accessible via address(this).balance like we did in the Making payments within smart contracts section above.

Awesome! Now our fictional small business owner can establish an invoice amount and a due date for payment within the smart contract, our fictional client can securely pay the invoiced amount to the contract, both parties can observe the contract’s balance, and the owner can withdraw the payment amount when it is due. We have now coded all components of the smart contract that we need for our simplified example. Next we will take a look at how to actually execute our smart contract using Ganache and the web3.js library.

Executing our smart contract

Alright so now that we have written our smart contract, we need to make it executable by putting it on the blockchain. The blockchain that we use is Ganache, a personal, in-memory Ethereum blockchain. We also want to interact with our smart contract. We will do so by running a local Node.js server and loading the web3.js library, a popular JavaScript API for Ethereum. I go over how to use Ganache and the web3.js library in a previous blog, so I won’t dive into too much detail here. We will start by installing the dependencies.

$ nvm use 12 && npm install ganache-cli solc@0.6.4 web3

Now we can launch Ganache and get a blockchain running on our own computer.

$ node_modules/.bin/ganache-cliGanache CLI v6.10.2 (ganache-core: 2.11.3)
Available Accounts
==================
(0) 0x4B33Eb9c62cB022e47Ac3988B8Df17cA34F4E529 (100 ETH)
(1) 0x4af81D2a714C00ee57e251d6c313eC88Cd83057A (100 ETH)
(2) 0xa9f5f1Eb2F9d4229dE9EF04C44673D1CCF6a67a8 (100 ETH)
(3) 0x15220064f048274c48d583098D21D4443837cbE4 (100 ETH)
(4) 0xf5331350AD5dE1d78B7BA08cEA413d6Af488F3ec (100 ETH)
(5) 0x2e7B78f24b31d57aF746ddE4DCF733bCbb419909 (100 ETH)
(6) 0xC3ad48e45f07045EcB8a7E57858fa3bd6e37f05D (100 ETH)
(7) 0x8c76de15e16F59634e07B1eB4D096F75ca349F71 (100 ETH)
(8) 0xe23cd7d5dff67ACdc6b63473A60Bfb2C6d5C9d2c (100 ETH)
(9) 0x847dB651f6A08bc016c6CCb593ba6aE74Bb83D50 (100 ETH)
Private Keys
==================
(0) 0x369a03a1f5e794565f9924e19545094578ad169f4f4f061f91b3c530fc83dab8
(1) 0xc02a84d626a32564578a3826bc752b0e0c142010605390dae5429154bedc6179
(2) 0x502c98cd8d350ab0d369a72d1a658aced668a9f4ce00fde67b3b370187cd831c
(3) 0x0ad9810b20788125723917cd710eca2689fcd5feff7a6cfafe9709ac1a8f59d6
(4) 0x98761dd7911f69ef8aeebe4d5dc9b7fdd085b7987597ecd3dd94cd94f0fd17b8
(5) 0x469a8a89fbadc043db675398a8e63c3462b7a20b5d62343de7ae68c457975363
(6) 0xf45fae0de3462a4875a2fe6ff1892dd30f16ee408145833cc5d6ec75ffa301ee
(7) 0xe6ea6f817ce48f22f584bc0457def99dbc6e77ee571290e765c2f12c1ef23a02
(8) 0xcd6c3ddec9cca1f938efbf2133de07c326194b1d84c6c4c4aae2123fe112168c
(9) 0x2fbfe7d395fc7a4e58740b308ebeac874fe91e286ec861ef9f004e580ae549b4
HD Wallet
==================
Mnemonic: slight famous become exact route monkey bottom fancy time elbow middle candy
Base HD Path: m/44'/60'/0'/0/{account_index}
Gas Price
==================
20000000000
Gas Limit
==================
6721975
Call Gas Limit
==================
9007199254740991
Listening on 127.0.0.1:8545

Let’s arbitrarily pick one address to represent our fictional small business that is providing the service and a separate address to represent our fictional client that is consuming the service.

$ node
> const serviceProvider = '0x4B33Eb9c62cB022e47Ac3988B8Df17cA34F4E529'
> const serviceConsumer = '0x4af81D2a714C00ee57e251d6c313eC88Cd83057A'

We can view the details of our newly created accounts using the web3 library.

> Web3 = require('web3');
> web3 = new Web3('http://127.0.0.1:8545');
> web3.eth.getBalance(serviceProvider).then(console.log);
100000000000000000000> web3.eth.getBalance(serviceConsumer).then(console.log);100000000000000000000

We see that each account came with 100,000,000,000,000,000,000 wei (100 Ether) preloaded, so we are ready to start executing some transactions on Ethereum! Our first transaction will be to get our smart contract deployed to the blockchain. In a separate window, we use the solcjs Solidity compiler that we installed earlier to compile our SmartInvoice source code into .bin and .abi files.

node_modules/.bin/solcjs --bin --abi 'SmartInvoice.sol'

You will notice two new files appear in your project: the SmartInvoice_sol_SmartInvoice.abi file and the SmartInvoice_sol_SmartInvoice.bin file. We need both of these files to deploy our smart contract to Ethereum.

> abi = JSON.parse(fs.readFileSync('SmartInvoice_sol_SmartInvoice.abi'));
> bytecode = fs.readFileSync('SmartInvoice_sol_SmartInvoice.bin').toString();
> contract = new web3.eth.Contract(abi);
> contract.deploy({data: bytecode, arguments: [50]}).send({ from: serviceProvider, gasPrice: web3.utils.toWei('0.000000098', 'ether'), gas: 1500000}).then((deployedContract) => { contract.options.address = deployedContract.options.address; console.log(deployedContract.options.address);});
0x07F063004f24AC5e0F8691b08Ca3D2f1001F5C5B

We chose 0.000000098 as the gasPrice because, according to Eth Gas Station, that is the recommended gas price to process a transaction at a standard rate as of the time of this blog. In Ganache CLI, we see the following output:

Transaction: 0xa3fcfebd436854cf851007b7aa881fe2f751ceaa3671c08c0f3f473b50b34771
Contract created: 0x07f063004f24ac5e0f8691b08ca3d2f1001f5c5b
Gas usage: 302988
Block Number: 1
Block Time: Fri Oct 02 2020 14:15:03 GMT-0400 (Eastern Daylight Time)

Let’s store the address of the contract in a new variable. We will need it later in this blog.

> const contractAddress = '0x07f063004f24ac5e0f8691b08ca3d2f1001f5c5b'

Using web3, we can also see the cost of executing this transaction to the small business owner’s account.

> web3.eth.getBalance(serviceProvider).then(console.log);99970307176000000000

That transaction cost 29,692,824,000,000,000 wei (0.029692824 Ether) to process. We can verify this because 302,988 units of gas * 0.000000098 Ether per unit of gas = 0.029692824 Ether. At the time of this blog, 1 Ether cost $344.45 USD meaning that this transaction cost $10.22 USD to produce. With this one-time cost our smart contract now exists on the blockchain forever, or at least until we decide to modify it.

Our smart contract is deployed on Ethereum meaning that we can finally call the functions of the contract that we defined above! Let’s start by verifying the initial balance of the contract by calling the getContractBalance method that we wrote as well as the implicit getter functions for our dueDate and invoiceAmount variables.

> contract.methods.getContractBalance().call(console.log);null 0> contract.methods.dueDate().call(console.log);null 1601662703> contract.methods.invoiceAmount().call(console.log);null 50

Using these, we can see the starting balance of the contract, the due date for payment, and the invoice amount set by the small business providing the service.

Next, let’s attempt to transfer money to the smart contract from the account of the client consuming the service.

> web3.eth.sendTransaction({from: serviceConsumer, to: contractAddress, value: 10});(node:57347) UnhandledPromiseRejectionWarning: Error: Returned error: VM Exception while processing transaction: revert Payment should be the invoiced amount.

We can see this same outcome reflected in Ganache CLI.

Transaction: 0xf7456725d99cf2a0e5aea5ce93a4647183aa446c1654ec36618db947bbe690d9
Gas usage: 22007
Block Number: 2
Block Time: Fri Oct 02 2020 14:28:59 GMT-0400 (Eastern Daylight Time)
Runtime Error: revert
Revert reason: Payment should be the invoiced amount.

This illustrates the implication of a reverted function call.

> web3.eth.getBalance(serviceConsumer).then(console.log);99999559860000000000

The client’s account was charged 440,140,000,000,000 wei (0.00044014 Ether) to process this transaction. We can verify this because 22,007 units of gas * 0.00000002 Ether per unit of gas = 0.00044014 Ether or, by today’s conversion rate, $0.15 USD. For this transaction 0.00000002 Ether per unit of gas was used rather than the 0.000000098 Ether because that is the default gas price for our Ganache instance.

In addition, we can verify that the transaction was reverted by checking the balance of our smart contract.

> contract.methods.getContractBalance().call(console.log);null 0

As we can see, the contract still has no balance. Let’s attempt the transaction again this time using the expected payment amount.

> web3.eth.sendTransaction({from: serviceConsumer, to: contractAddress, value: 50});

We can see in Ganache CLI that this transaction was successful!

Transaction: 0xab7ce0222dd7d6398d2eb5de6e222591e6f4777c2683254167eb616903bf2ac3
Gas usage: 21876
Block Number: 3
Block Time: Fri Oct 02 2020 15:36:47 GMT-0400 (Eastern Daylight Time)

We can verify this by checking the client’s account balance.

> web3.eth.getBalance(serviceConsumer).then(console.log);99999122339999999950

Previously, the client’s account had 99,999,559,860,000,000,000 wei (99.99955986 Ether) and now has 99,999,122,339,999,999,950 wei (99.99912233999999995 Ether): a difference of 437,520,000,000,000 wei (0.00043752 Ether). We can see in the transaction record in Ganache CLI that 21,876 units of gas was used to process the transaction. So 21,876 units of gas * 0.00000002 Ether per unit of gas = 0.00043752 Ether or $0.15 USD, by today’s conversion rate, was transferred from the client’s account to the smart contract.

We can then verify that the amount is now held in our smart contract via another call to our getContractBalance method.

> contract.methods.getContractBalance().call(console.log);null 50

Let’s also verify that the payment was not also transferred to the small business’ account.

> web3.eth.getBalance(serviceProvider).then(console.log);99970307176000000000

Great! The balance is the same as before. The final step is to verify that the small business can withdraw the funds after the agreed upon due date. We first check that a random account can’t withdraw the balance using one of the remaining eight accounts created when we first launched Ganache.

> const randomAccount = '0xa9f5f1Eb2F9d4229dE9EF04C44673D1CCF6a67a8'
> contract.methods.withdraw().send({from: randomAccount});
(node:57347) UnhandledPromiseRejectionWarning: Error: Returned error: VM Exception while processing transaction: revert Only the service provider can withdraw the payment.

We can see in Ganache CLI that this transaction was not successful.

Transaction: 0x187ee6a3c2928c4428fe40095fb6bf9bca39f430e34ae274b256071c4ac9f4bb
Gas usage: 22185
Block Number: 4
Block Time: Fri Oct 02 2020 17:32:27 GMT-0400 (Eastern Daylight Time)
Runtime Error: revert
Revert reason: Only the service provider can withdraw the payment.

We can verify this by checking that the previous payment remained the balance of the contract.

> contract.methods.getContractBalance().call(console.log);null 50

Let’s attempt the transaction again this time using the small business’ account.

> contract.methods.withdraw().send({from: serviceProvider});

We can see in Ganache CLI that this transaction was successful!

Transaction: 0x50b0f6b683d711e9e033b71bae5c1f0789133c799249d3629a1e256d70f156ce
Gas usage: 30401
Block Number: 5
Block Time: Fri Oct 02 2020 17:37:04 GMT-0400 (Eastern Daylight Time)

We can verify this by checking the balance of the small business’ account.

> web3.eth.getBalance(serviceProvider).then(console.log);99969699156000000050

Voila! We see that the 50 wei has been added to the account’s balance. The account was still charged 30,401 units of gas * 0.00000002 Ether per unit of gas = 0.00060802 Ether to process the transaction of transferring the funds from the smart contract to their account. As a double-check we can check that the balance of the smart contract has been withdrawn.

> contract.methods.getContractBalance().call(console.log);
null 0

In this section, we took our smart contract, compiled it down to an executable binary file, deployed it to the blockchain, and began executing transactions against it all of which was recorded and accessible via this distributed ledger.

How do smart contracts and the blockchain help small businesses?

Invoicing is made simpler. Invoicing today is time consuming and cumbersome. According to Business Wire, small business owners spend 3.5 hours per month creating, sending, and reviewing invoices, and sometimes mistakes are made that contribute to late payments. Forbes lays out several common invoicing mistakes many of which are alleviated if not eradicated using smart contracts and the blockchain. The first mistake is forgetting to send an invoice or not following up on unpaid invoices. One great feature of smart contracts is that they can interact with other smart contracts. A small business owner could include our simple SmartInvoice contract as a component of a parent smart contract such as a sales contract or a services contract. In this way, an invoice already exists as soon as the work begins. Smart contracts also enable automation of tasks including the instantiation of the contract and follow-ups. A second common invoicing mistake is incorrect details or use of unclear payment terms. For example, the invoice may get sent to the wrong client or to the wrong department, or it might use “net 30” to indicate that the full payment is due in 30 days which may be unfamiliar terminology to the client. These issues are alleviated because the terms and details of the smart contract, like invoice amount and due date, are clearly written into the contract and indefinitely accessible on the blockchain so that no party can contest them. In addition, the smart contract is tied to both the owner’s and the client’s accounts and the transfer of payment is handled directly between the two rendering the use of physical addresses obsolete. Finally, even if the invoice is sent, received by the right contact, and actively pursued, payments may still get delayed if small business owners forget to track their invoices and to back them up. At its core, blockchain is a distributed ledger technology where data is replicated across a network of independent computers. Smart contracts and the Ethereum blockchain leverage this to record all transactions with a smart contract giving both service provider and service consumer easy, digital access to the details of their smart contracts and making data loss highly unlikely.

Transactions on the blockchain cost small business owners less than current forms of payment as the transaction size increases. According to the Quickbooks survey from the Small businesses struggle with collecting payment on time section above, 38% of the clients of small businesses prefer to pay with a debit or credit card making it their second most preferred payment form; cash being the first at 58%. Square estimates, as of the time of this blog, that U.S. businesses pay between 2.87% and 4.35% in credit card processing fees per transaction. As the size of the payment increases this fee grows substantially, e.g. an invoice for $1,000.00 USD would cost the business between $28.70 USD and $43.50 USD for the processing fee. This fee is actually a culmination of individual fees charged by the central authorities, i.e. the card issuer, the card network, and the payments processor, to process the transaction and cover them for risks such approving the sale and fraud. Thus it comes as no surprise that as the size of the payment increases, and therefore the risk of covering the payment increases, the fee to process that transaction increases. On the blockchain, instead of a fluctuating processing fee determined by some central authorities and based on the size of the payment, processing fees are paid to the network of nodes that process the transaction where, because the blockchain network validates every transaction as part of a shared ledger, transactions are less prone to fraud and less risky. While this processing fee can vary based on network traffic, it is often less than what a credit card processor will charge, and it fluctuates with the amount of work to be done rather than the size of the payment. For example, as we saw in the Executing our smart contract section above, our smart contract cost $10.22 USD to execute which is the same price that the small business owner would pay whether the size of the payment was $1,000.00 USD or $10,000 USD. In addition to a processing fee, there are other fees that standard transactions charge, i.e. foreign transaction fees, which become irrelevant when the transaction occurs on a blockchain like Ethereum.

Lastly, smart contracts are extendable. This gives small business owners the freedom to customize the contents of a smart contract based on their specific business processes. This could include various components like advance payments like retainers or deposits, discounts for paying the invoice before its due, and fees for not meeting requirements of the contract on time.

What were we talking about, again?

As we learned at the beginning of this blog, collecting payment quickly and accurately is the primary challenge for self-employed workers and small business owners. When payment is not received on time, small businesses are unable to pay their own expenses, not the least of which is paying their employees and themselves. This makes late payments the lead factor contributing to 50% of small businesses failing within five years. The owners of these businesses are our friends and neighbors; especially those of us lucky enough to call New York City our home. According to an article in Small Business Trends published in 2019, New York City is home to the most small business owners with a total of 411K which is even greater than the combined totals of runners-up Los Angeles at 243K, San Francisco at 84K, and Boston at 81K small business owners. While small business owners are a minority compared to the working population, data shows that most of us actually want what these individuals have been brave enough to do. In fact, according to a survey run by the Organisation for Economic Co-operation and Development in 2015, 69% / 62% of adult men and 58% / 52% of adult women in the United States and Canada respectively want to build their own businesses. While this presents a clear economic opportunity, a convincing humanities argument could also be made to build solutions to problems that inhibit achievement of a dream so common across our fellow human beings.

Today, one in three small business owners and self-employed workers already report using some kind of technology in financial areas of their business with 36% using accounting software and 36% using bookkeeping software so using blockchain technology for invoicing is not an unimaginable next step for these businesses to adopt.

And it all starts with enabling small business owners to collect payments when they are due!

If you are a small business owner and you’d like to get some hands on experience building smart contracts on Ethereum with Solidity and JavaScript, clone the source code from my GitHub of the application that we built throughout this blog and run it on your local machine.

About the author

Colin Kraczkowsky is passionate about building solutions that solve people’s problems and loves to learn and share his thoughts on new technologies. His latest interest is in blockchain, specifically Ethereum development, and its applications to solving problems for small businesses including sole proprietors, the self-employed, and solopreneurs. Colin’s professional history includes working in both enterprise and startup environments to code web and mobile applications, launch new products, build mockups and prototypes, analyze metrics, and continuously innovate.

In his spare time, Colin can be found checking out an REI camp bundle for a weekend away in the woods, field testing the latest HOKAs, hunting fresh powder on the mountain, or surfing the Horror section on Netflix.

Connect with Colin — https://www.linkedin.com/in/colinkraczkowsky

--

--

Colin Kraczkowsky
The Startup

Problem solver wielding JavaScript and Solidity as my tools. Scholar of the newly possible.