License

In this example, we will explore a licensing system, with a Licensor, Licensee, and a License. The Licensor grants the Licensee a License, which they can use the review a product. However, the Licensee may not publish their review of the product until the review has been Approved or Commissioned. To help ensure compliance, the Licensee must pay some amount of money to obtain the license, which will be returned to them upon publishing the approved or commissioned review.

We wish to enforce the following points:

  1. The Licensee may not publish their review without Approval or Commission from the Licensor.
  2. If the Licensor issues an Approval, then the Licensee may publish their review of the product, and the Licensee will receive the fee they paid for the License.
  3. If the Licensor issues a Commission, they must include some money as a payment for the publishing of the review.
  4. If commissioned, the Licensee may publish their review of the product, and the Licensee will receive both the money from the commission as well as the fee they paid for the License.

The code in the file License.obscontains several tasks, each labeled // TODO TASK #: ... . You do not have to do the tasks in any particular order, but they are numbered by anticipated difficulty, with lower numbers being less time consuming.

The Licensee has a pay transaction, which can be used to send them money, whose signature is shown below.


transaction pay(Licensee@Owned this, Money@Owned >> Unowned money);

Below are the declarations for the various tokens: License, Approval, and Commission.


asset contract License {
    state Unknown;
    state Valid;

    License@Unknown(Licensor@Unowned issuer, int feeAmount);

    transaction checkToken(License@Unknown >> Valid this, Licensor@Unowned licensor);
    transaction getFeeAmount(License@Unowned this) returns int;
}

asset contract Approval {
    state Unknown;
    state Valid;

    Approval@Unknown(Licensor@Unowned issuer);

    transaction checkToken(Approval@Unknown >> Valid this, Licensor@Unowned licensor);
}

asset contract Commission {
    state Unknown;
    state Valid;
    state Completed;

    Commission@Unknown(Licensor@Unowned issuer, Money@Owned >> Unowned _payment);

    transaction checkToken(Commission@Unknown >> Valid this, Licensor@Unowned licensor);
    transaction getPayment(Commission@Valid >> Completed this) returns Money@Owned;
}