COMP6451 Ethereum Programming
Ethereum Programming
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: THEend8_
COMP6451
Assignment 2 (version 2)
Ethereum Programming
Total Marks: 35
Background
A variety of schemes are used to sell goods in such a way as to yield the highest
profit for the seller. English Auctions, used in Australia for selling real estate,
are probably the most familiar to you: bidders take turns to offer increasingly
high prices, until one bidder remains who has offered the highest price, and no
other bidder is prepared to offer any higher price. The auction is then declared
closed by the auctioneer, and the highest bidder is declared the successful buyer,
at a price equal to their highest bid.
This approach has some disadvantages from the point of view of an unsuc-
cessful bidder. During the course of the auction, they were required to reveal
the highest price that they were prepared to pay. Other sellers wishing to sell
similar items can then take advantage of this fact and refuse to sell for less than
this price, depriving the purchaser of the possibility of a purchase at a lower
price, even when there is no competition from other bidders. It would be prefer-
able if the winning bidder for an auction were determined in a way that does not
reveal the bids of the losing bidders. In part 1 of this assignment we develop a
way to achieve this. Even better would be to also hide the identity of the losing
bidders. This is addressed in a stretch goal in part 2 of the assignment.
Hiding the bids of losing bidders can be achieved through use of a Dutch
Auction. Such an auction swaps the roles of the buyers and seller, and proceeds
by successive decreases of the price, until a buyer is found who is prepared to
∗See footnotes for corrections
1
pay that price. That is, the seller first states a high price, and asks the buyers
for an offer to buy at that price. If no buyer states that they are prepared to
pay that price, the seller reduces the price, and again asks for an offer. This
process repeats, with the price decreasing over time, until a buyer is found.
In this assignment, we will apply this approach to develop a smart contract
for a market where ERC-20 tokens can be bought and sold. Compared to
the sale of a single item, we have some additional requirements. Consider a
situation where a seller wishes to sell some number N of ERC-20 tokens of the
same type. Suppose there are n ≥ 1 bidders, all offering to buy b1, . . . , bn tokens
at the current seller price p per token. Bidder i may receive a number x ≤ bi
tokens from this seller. Bidder i will pay price p per token when receiving x
tokens from this seller, for total cost x× p.
• If
∑
i=1...n bi ≤ N , each buyer i should receive exactly bi tokens, leaving
N −∑i=1...n bi remaining to be sold. The seller has the option of further
reducing the price to sell these tokens if they wish.
• If
∑
i=1...n bi > N , then there is contention for the tokens being sold, and
we need a rule to determine how many tokens each buyer receives. We will
take the attitude that the buyer who has been waiting to buy the longest
will have their order filled first. For that, we need a way to determine
which buyer that is, without revealing the price that they are prepared
to pay too early. We resolve that by using bid blinding. We maintain
a counter bid-number initially 0. When a buyer submits a buy order, it
is assigned the current bid-number, and bid-number is incremented. The
bid itself is blinded : it should not reveal the number of tokens that the
buyer is offering to buy, nor the price they are prepared to pay for each
token. When the seller’s price reaches the price that the buyer is prepared
to pay, the buyer opens, or reveals their bid, making the number of tokens
and the price public. It should not be possible for the buyer to cheat by
revealing a number of tokens or a price that differs from the numbers used
in their initial blinded bid.
In the context of a market service, that provides matching between multiple
sellers and buyers, there is a similar issue when multiple sellers are offering to
sell the same kind of tokens, but at potentially different prices. ERC-20 tokens
in the same asset (i.e., issued from the same smart contract) are fungible, so the
buyers will not care which seller’s tokens they receive. When matching buy bids
and sale offers, the bids should be matched against the lowest price sale offers
first. For sale offers at the same price, the older sale offers should be used first
to supply the buyers. To enable this, when a block of tokens is first offered for
sale, it is associated with an offer-number.
Note that where an offer to sell at price p is matched with a bid to buy at
price q ≥ p, the buyer pays the lower price p. A bid to buy at a price q should
not be matched with an offer to sell at a price p > q: such an open bid is left
in the market for possible matching in later rounds.
2
For example, suppose we have the following sale offers and opened buy bids,
all for the same token type, in a given matching round.
• Seller 1 offers 5 tokens at price 3 ETH each, with offer-number 1
• Seller 2 offers 10 tokens at price 2 ETH each, with offer-number 2
• Buyer 3 bids for 5 tokens at price 3 ETH, with bid-number 1
• Buyer 4 bids for 20 tokens at price 2 ETH ,with bid-number 2
Then
• Buyer 3, who has the oldest bid, is handled first. Their bid is matched to
Seller 2’s lower priced offer, and Buyer 3 receives 5 tokens at price 2 ETH
each. This leaves 5 tokens in Seller 2’s offer.
• Buyer 4 is handled next. They receive 5 tokens at price 2 ETH from Seller
2’s offer, for which they pay 10 ETH. Next, we consider matching Buyer
4 to Seller 1. However, Buyer 4 is not prepared to pay the price of 3 ETH
in Seller 1’s offer, so this is not a match.1
• Buyer 4’s bid was not completely filled, and remains open as a bid for 15
tokens at price 2 ETH, unless Buyer 4 elects to withdraw this offer during
the next Bid Opening round. (See below for information about when bids
and offers can be changed.)
Part 1 (25 marks)
Develop a DutchMarket smart contract in Solidity implementing a market for
ERC-20 tokens that implements the above ideas. More precisely, the contract
should have the following functionality:
• Buyers and Sellers should be able to create accounts at the smart contract,
containing an amount of ETH, and a set of ERC-20 tokens of different
kinds. (Token kinds are identified by the address of the smart contract
from which they were issued.)
• ERC-20 tokens held in the market should be under the control of the
DutchMarket contract, so that they cannot be sold elsewhere.
• Buyers and Sellers should be able to deposit and withdraw both tokens
and ETH currency from their accounts.
• Sellers should be able to offer to sell a block of N tokens of the same kind
from their account, at a specified price.
• Sellers should be able to reduce the price on an outstanding offer, but not
increase the price.
1Version 1 incorrectly matched Buyer 4 and Seller 2.
3
• Sellers should be able to withdraw an offer to sell.
• Buyers should be able to make blinded bids to buy tokens. A bid states the
token type for the purchase, the number of tokens to be bought, as well
as a maximum price. These details of the bid should not be deducible by
anyone who is monitoring the blockchain. However, the cryptographic ad-
dress of the bidder may be revealed (see the next section, which addresses
hiding of the bidder identity.)
• When a seller reduces the price to an amount that a buyer is prepared
to pay, the buyer makes the purchase by opening a matching blinded bid.
This reveals the token type, number of tokens and maximum price.
• Once a buy offer has been opened, it remains visibly open.
• A buyer may withdraw an open or closed offer.
• The market operates in a repeated sequence of modes: Deposit/Withdraw,
Offer, Bid Opening and Matching, which restrict the operations that par-
ticipants may perform while the system is the mode. Each mode applies
for a period of 5 minutes, at the end of which, the market switches to the
next mode in the sequence (Matching is followed by Deposit/Withdraw).
The operations permitted in each mode are as follows:
– Deposit/Withdraw: buyers and sellers may deposit and withdraw
from their accounts
– Offer: Sellers may make new offers to sell, withdraw offers, and
reduce the price on existing offers to sell.
– Bid Opening: Buyers may place new blinded bids to buy. Buyers
may also open blinded bids. They may also withdraw open or blinded
bids.
– Matching: Outstanding offers to sell are matched with opened bids
to buy, according to the priority rules described in Section 1.
• For each matching pair, the appropriate number of tokens k is transferred
from the seller’s account to the buyer’s account, and k times the offer
price is transferred from the buyer’s account to the seller’s account. (The
service does not charge a market fee to buyers and sellers.)
• Negative account balances are prohibited. Where execution of a match
would create a negative account balance in either the buyer or seller’s
account, that match should not be executed. To the largest extent possi-
ble, the market design should prevent the possibility that such improper
matches will occur.
• As much as possible, the implementation of the smart contract should
minimize the gas cost that users (buyers and sellers) should be required
to pay for their transactions.
4
The project has a strict deadline, so you should attempt the Part 1 speci-
fication first. For additional marks once you have completed this, attempt the
stretch goal.
Part 2 - Stretch Goal (10 Marks)
As noted above, blinded bids still reveal the identity of the bidder, at least by
way of their Ethereum address, because a user will open an account with that
address, and then submit bid transactions to the market smart contract that are
signed with the key for that address. This may be an issue for bidder privacy,
and other bidders may prefer not to bid when they see that there is a competing
bidder with a large cash balance, or who has a reputation of placing very high
bids.
As a stretch goal, modify your solution to allow the bidder identity to be
obscured by the following technique. Instead of placing blinded bids using trans-
actions signed by the same address A under which they have opened an account
at the market, users may submit blinded bids using transactions signed by an-
other address B. These blinded bids state, as usual, the token type, number
of tokens and a price. However, in addition, the bid states the address of the
real bidder A. All of this information (except B) should be hidden, until the
bid is opened. At the time of opening, the usual bid information, as well as A’s
address, should be revealed, so that matching of the bid will affect A’s account
in the usual way.
Note that the information revealed at the time of opening such a bid should
prove that it really was A’s intention to place the bid transaction signed by B.
It should not be possible for any user other than the real bidder A to use this
mechanism to cause changes to A’s account. For this, the information revealed
by bid opening should be a message, signed using address A, that states the
usual bid information. The market smart contract should verify this signature
before accepting the bid as valid and assigning it to user A. (You might like
to think of the mechanism as bids being like sealed envelopes containing signed
letters.)
Hint: The Ethereum function ecrecover and frameworks such as Web3.py
or Web3.js are relevant to this part. You may also wish to investigate proposals
such as EIP-721 and EIP-2612.
Deliverables
Submit the following. Note that it is not a requirement of the assignment to
develop a Graphical User Interface for this application - where code other than
Solidity code is necessary, invocation using command line instructions suffices
to meet the requirements.
1. (8 marks) A report (pdf format) describing your design and implementa-
tion of the overall system. The report should
5
• Describe the data model, and how you have chosen to implement this
design using Solidity data structures.
• In case use of the smart contract requires off-chain computations
not implemented in the smart contract, explain what this code does
and how to compile and/or operate it. You are not required in this
assignment to develop a fancy user interface for any such code: some
simple command-line scripts suffice.
• For each of the requirements above, briefly indicate where and how
your code meets the requirement. Briefly explain each of the func-
tions in your code. In case you identified any missing requirements
or specification ambiguities in the course of your analysis of the ap-
plication, state what these are and what you have done to resolve
and implement them.
• Provide an analysis of the running costs in gas and Australian dollars
of the application from the point of view of the buyers and sellers,
and how this depends on factors such as the total number of bids
and offers. Take into account current information on the costs of
transactions on the Ethereum public blockchain, and the gas costs of
running your code.
• Describe any security considerations concerning the system and its
operation that you consider should be pointed out to the users. Are
there any specific traps that the user needs to avoid in using the
system, and if so, what are strategies that the user can apply to
avoid these traps.
• Explain how your code avoids common Solidity security vulnerabili-
ties like reentrancy attacks.
• Reflectively discuss the overall suitability of the Ethereum platform
for this application.
Proper acknowledgement of any sources of information or libraries you
have used in your project is required.
2. (10 marks) Submit a directory with all Solidity and ancillary code neces-
sary to build and run your implementation using Truffle.2 In particular
there should be a directory contracts containing smart contracts in So-
lidity for your implementation of the basic functionality. Your code should
be well documented.
If you have used any public Javascript libraries, to avoid an overly large
submission file, do not include these, but ensure that there is sufficient
information in your submission that these can be automatically installed.
In particular, include your package-lock.json file.
2You may choose to do initial development in Remix, but loading your code into Remix
creates additional work and inconvenience for the grader, so you should submit in a format
that allows testing to be done using Truffle.
6
3. (7 marks) Include a directory test containing test cases to validate the
correctness of your smart contract implementation. Your report should
describe the approach that you have taken to testing, and summarize
the test scenarios that you have constructed. It should be possible to
execute your tests using the Truffle testing framework. You may also test
by running a Ganache instance of the Ethereum blockchain. If specific
command line arguments are required to run your tests, include a script
that allows the appropriate calls to be made easily by the marker. In
any case, the report should contain all the information that is required to
determine how to run your tests.
4. (10 marks) Once you have met the basic requirements, attempt the stretch
goal. If you attempt this part, your report should contain a section de-
scribing what you have done for this part, you should include test cases
for this functionality, and it should be clear from your report how to run
these test cases.
Resources and Hints for Testing
For Part 1, it will probably be possible to write tests for your code entirely us-
ing test scripts written in Solidity. Part 2 is more challenging, since it requires
constructing ECDSA signatures, for which Solidity does not provide good sup-
port. (The built-in function ecrecover only does signature verification.) For
this, it is better to write tests in Javascript. In general, JavaScript testing
is the more powerful approach (better supported because off-chain application
code for interacting with the Ethereum blockchain is most commonly written in
JavaScript) and there are a number of JavaScript libraries that support testing.