3.2. BookkeepersBookkeepers defined dozens of APIs of legal behaviors regarding corporate governance and share transactions, so as to manage and control the identification of actors, conditions, procedures and legal consequences of the relevant legal behaviors.
3.2.1. Functions of BookkeepersWhen users exercise their rights, Bookkeepers will call Shareholders Agreement and the relevant Registers as per legal logic, so as to check what conditions need to be satisfied to conduct the relevant legal behaviors (or what parameters need to be relied on for the subsequent calculations), and, together with the input parameters obtained from the API, Bookkeepers will make decisions on whether the conditions are fulfilled or calculate the specific values of the intermediate parameters. If all conditions are fulfilled, Bookkeepers will call the relevant Registers to update the states of book-entry interests or record the contents of the legal behaviors, such as expression of intention, or action tracks of the behaviors.
For example, when a shareholder votes on a motion, it needs to call the "Cast Vote" API of General Keeper, input the subject motion number and express its attitude as support, against or abstain, thereafter, General Keeper will call Reg Center to retrieve the user number of shareholder and further call the “Cast Vote” API of
General Meeting Minutes Keeper (“GMM Keeper”) so as to hand over the control rights on the subsequent processing steps, and then,
GMM Keeper will:
(1)retrieve the motion object from General Meeting Minutes;
(2)retrieve the voting rule from Shareholders Agreement as per the voting rule number specified in the motion object, and deduce the voting period accordingly;
(3)determine whether it is in the voting period as per the current timestamp;
(4)if within the voting period, call the Register of Members to verify whether the voter is a shareholder of the company;
(5)If it is a shareholder, then check the entrust arrangements from the Delegate Map of the motion, and then call the Register of Members again to retrieve and calculate the total voting rights entrusted from the principals as well as represented by the voter;
(6)Finally, store the voting information (user number, voting attitude, total voting rights, voting time, etc.) in the General Meeting Minutes.
From the above example, it can be deduced that Bookkeeper acts as the control center of verifying the conditions precedent and monitoring the logical flows of the legal behaviors.
In order to satisfy the size requirements of EIP-170, ComBoox defines two types of smart contracts, namely, General Keeper and several Sub-Bookkeepers.
3.2.2.General KeeperGeneral Keeper sits at the uppermost layer of the company book-entry system and has the following functions:
(1)Acts as the only entry of the company's book-entry system for write operation commands and is responsible for routing write commands to specific Sub-Bookkeeper;
(2)Acts as the address registration center for Registers, and responses the address of specific Register as per its sequence number;
(3)Represents the legal entity of the company and conducts legal behaviors on behalf the company on-chain, e.g. signing or executing smart contracts, making payments in tokens, exercising voting rights, etc;
(4)Represents the company to hold cryptocurrencies such as ETH and CBP etc., and makes payments in accordance with the resolutions of General Meeting of Members or Board of Directors;
(5)Temporarily keeps ETH consideration incurred from share transfer transactions, which can be picked up by the seller to its public key account thereafter.
3.2.3.Sub-BookkeepersSub-Bookkeepers are the core computation layer controlling the identity verification, conditions, procedures and legal consequences of legal behaviors, which includes:
(1)
Register of Constitutions Keeper ("ROC Keeper"): has write permissions to Register of Agreements, and controls the legal behaviors of creating, circulating, signing, enactivating, and accepting Shareholders Agreements;
ROC Keeper API
function createSHA(uint version, uint caller) external;
function circulateSHA(address body, bytes32 docUrl, bytes32 docHash, uint caller) external;
function signSHA(address sha, bytes32 sigHash, uint caller) external;
function activateSHA(address body, uint caller) external;
function acceptSHA(bytes32 sigHash, uint caller) external;
(2)
Register of Directors Keeper ("ROD Keeper"): has write permissions to Register of Directors, and controls the legal behaviors of inauguration, dismissal, and resignation of directors or executive officers;
ROD Keeper API
function takeSeat(uint256 seqOfMotion, uint256 seqOfPos, uint caller) external;
function removeDirector (uint256 seqOfMotion, uint256 seqOfPos, uint caller) external;
function takePosition(uint256 seqOfMotion, uint256 seqOfPos, uint caller) external;
function removeOfficer (uint256 seqOfMotion, uint256 seqOfPos, uint caller) external;
function quitPosition(uint256 seqOfPos, uint caller) external;
(3)
Board Meeting Minutes Keeper ("BMM Keeper"): has write permissions to Board Meeting Minutes, and controls the legal behaviors of creating and proposing board motions, appointing voting delegate, casting vote, counting of vote results, and executing actions. The motions concerned include the appointing and removing managers, reviewing contracts, paying tokens, and calling on-chain smart contracts;
BMM Keeper API
function nominateOfficer(uint256 seqOfPos, uint candidate, uint nominator) external;
function createMotionToRemoveOfficer(uint256 seqOfPos, uint nominator) external;
function createMotionToApproveDoc(uint doc, uint seqOfVR, uint executor, uint proposer) external;
function proposeToTransferFund(
address to, bool isCBP, uint amt,
uint expireDate, uint seqOfVR, uint executor, uint proposer
) external;
function createAction(
uint seqOfVR, address[] memory targets, uint256[] memory values,
bytes[] memory params, bytes32 desHash, uint executor, uint proposer
) external;
function entrustDelegaterForBoardMeeting(uint256 seqOfMotion, uint delegate, uint caller) external;
function proposeMotionToBoard (uint seqOfMotion, uint caller) external;
function castVote(uint256 seqOfMotion, uint attitude, bytes32 sigHash, uint caller) external;
function voteCounting(uint256 seqOfMotion) external;
function transferFund(
address to, bool isCBP, uint amt,
uint expireDate, uint seqOfMotion, uint caller
) external;
function execAction(
uint typeOfAction, address[] memory targets, uint256[] memory values,
bytes[] memory params, bytes32 desHash, uint256 seqOfMotion
uint caller
) external;
(4)
Register of Members Keeper ("ROM Keeper"): has write permissions to Register of Shares and Register of Members, and controls the legal behaviors of setting the maximum number of shareholders, setting hash locks on paid-in shares, releasing and withdrawing paid-in shares, and decreasing registered capital;
ROM Keeper API
function setMaxQtyOfMembers(uint max) external;
function setPayInAmt(
uint seqOfShare,
uint amt,
uint expireDate,
bytes32 hashLock
) external;
function requestPaidInCapital(bytes32 hashLock, string memory hashKey) external;
function withdrawPayInAmt(bytes32 hashLock, uint seqOfShare) external;
function payInCapital(uint seqOfShare, uint amt, uint caller) external payable;
function decreaseCapital(uint256 seqOfShare, uint paid, uint par) external;
function updatePaidInDeadline(uint256 seqOfShare, uint line) external;
(5)
General Meeting Minutes Keeper ("GMM Keeper"): has write permissions to General Meeting Minutes, and controls the legal behaviors of creating and proposing motions, appointing voting delegate, casting votes, counting vote results, and executing resolutions. The motions include nominating and removing directors, reviewing contracts, paying tokens and calling smart contracts;
GMM Keeper API
function nominateDirector(uint256 seqOfPos, uint candidate, uint nominator) external;
function createMotionToRemoveDirector(uint256 seqOfPos, uint caller) external;
function proposeDocOfGM(
uint doc, uint seqOfVR, uint executor, uint proposer
) external;
function proposeToDistributeProfits(
uint amt, uint expireDate, uint seqOfVR, uint executor, uint caller
) external;
function proposeToTransferFund(
address to, bool isCBP, uint amt, uint expireDate,
uint seqOfVR, uint executor, uint proposer
) external;
function createActionOfGM(
uint seqOfVR, address[] memory targets, uint256[] memory values,
bytes[] memory params, bytes32 desHash, uint executor, uint proposer
) external;
function entrustDelegaterForGeneralMeeting(uint256 seqOfMotion, uint delegate, uint caller) external;
function proposeMotionToGeneralMeeting(uint256 seqOfMotion, uint caller) external;
function castVoteOfGM(
uint256 seqOfMotion, uint attitude, bytes32 sigHash, uint caller
) external;
function voteCountingOfGM(uint256 seqOfMotion) external;
function distributeProfits(uint amt, uint expireDate, uint seqOfMotion, uint caller) external;
function transferFund(
address to, bool isCBP, uint amt,
uint expireDate, uint seqOfMotion, uint caller
) external;
function execActionOfGM(
uint seqOfVR, address[] memory targets, uint256[] memory values,
bytes[] memory params, bytes32 desHash, uint256 seqOfMotion, uint caller
) external returns(uint);
(6)
Register of Agreements Keeper ("ROA Keeper"): has write permissions to Register of Agreements and Register of Shares, and controls the legal behaviors of creation, circulation, and signing of Investment Agreements, as well as locking the subject equity, releasing and withdrawing the subject equity, issuing new shares, transferring share, terminating transaction, and paying consideration;
ROA Keeper API
function createIA(uint256 version, address primeKeyOfCaller, uint caller) external;
function circulateIA(address ia, bytes32 docUrl, bytes32 docHash, uint256 caller) external;
function signIA(address ia, uint256 caller, bytes32 sigHash) external;
function pushToCoffer(
address ia,
uint256 seqOfDeal,
bytes32 hashLock,
uint closingDeadline,
uint256 caller
) external;
function closeDeal(address ia, uint256 seqOfDeal, string memory hashKey) external;
function transferTargetShare(address ia, uint256 seqOfDeal, uint256 caller) external;
function issueNewShare(address ia, uint256 seqOfDeal, uint caller) external;
function terminateDeal(address ia, uint256 seqOfDeal, uint256 caller) external;
function payOffApprovedDeal(address ia, uint seqOfDeal, uint msgValue, uint caller) external;
(7)
Register of Options Keeper ("ROO Keeper"): has write permissions to Register of Options and Register of Shares, and controls the legal behaviors of inputting trigger events, exercising options, setting option’s pledge, paying off option, executing option’s pledge, requesting the against member to buy, paying consideration for the rejected deal’s equity shares, and executing the against member's pledge;
ROO Keeper API
function updateOracle(uint256 seqOfOpt, uint d1, uint d2, uint d3) external;
function execOption(uint256 seqOfOpt, uint caller) external;
function createSwap(
uint256 seqOfOpt,
uint seqOfTarget,
uint paidOfTarget,
uint seqOfPledge,
uint caller
) external;
function payOffSwap(uint256 seqOfOpt, uint256 seqOfSwap, uint caller) external payable;
function terminateSwap(uint256 seqOfOpt, uint256 seqOfSwap, uint caller) external;
function requestToBuy(
address ia,
uint seqOfDeal,
uint paidOfTarget,
uint seqOfPledge,
uint caller
) external;
function payOffRejectedDeal(
address ia,
uint seqOfDeal,
uint seqOfSwap,
uint caller
) external payable;
function pickupPledgedShare(
address ia,
uint seqOfDeal,
uint seqOfSwap,
uint caller
) external;
(
Register of Pledges Keeper ("ROP Keeper"): has write permissions to Register of Pledges, Register of Shares, and Register of Agreements, and controls the legal behaviors of refunding debts, extending secured period, creating, transferring, executing, locking, releasing, withdrawing and revoking pledges;
ROP Keeper API
function createPledge(
bytes32 snOfPld,
uint paid,
uint par,
uint guaranteedAmt,
uint execDays,
uint caller
) external;
function transferPledge(
uint256 seqOfShare,
uint256 seqOfPld,
uint buyer,
uint amt,
uint caller
) external;
function refundDebt(uint256 seqOfShare, uint256 seqOfPld, uint amt, uint caller) external;
function extendPledge(uint256 seqOfShare, uint256 seqOfPld, uint extDays, uint caller) external;
function lockPledge(uint256 seqOfShare, uint256 seqOfPld, bytes32 hashLock, uint caller) external;
function releasePledge(
uint256 seqOfShare,
uint256 seqOfPld,
string memory hashKey,
uint caller
) external;
function execPledge(
bytes32 snOfDeal,
uint256 seqOfPld,
uint version,
uint buyer,
uint groupOfBuyer,
uint caller
) external;
function revokePledge(uint256 seqOfShare, uint256 seqOfPld, uint caller) external;
(9)
Shareholders Agreement Keeper ("SHA Keeper"): has write permissions to Register of Shares and Register of Agreements, and controls the legal behaviors of exercising and accepting special shareholders' rights like Drag-Along, Tag-Along, Anti-Dilution and First Refusal;
SHA Keeper API
function execAlongRight(
address ia,
uint256 seqOfDeal,
uint256 seqOfShare,
uint paid,
uint par,
uint caller,
bytes32 sigHash
) external;
function acceptAlongDeal(
address ia,
uint256 seqOfDeal,
uint caller,
bytes32 sigHash
) external;
function execAntiDilution(
address ia,
uint256 seqOfDeal,
uint256 seqOfShare,
uint caller,
bytes32 sigHash
) external;
function takeGiftShares(address ia, uint256 seqOfDeal, uint caller) external;
function execFirstRefusal(
uint256 seqOfRule,
uint256 seqOfRightholder,
address ia,
uint256 seqOfDeal,
uint caller,
bytes32 sigHash
) external;
function computeFirstRefusal(address ia, uint256 seqOfDeal, uint caller) external;
(10)
List of Orders Keeper ("LOO Keeper"): has write permissions to List of Orders, Register of Shares, and Register of Members, and controls legal behaviors of registering, approving and revoking accredited investors, listing and withdrawing initial offers, sell orders, and placing buy orders;
LOO Keeper API
function regInvestor(uint userNo, uint groupRep, bytes32 idHash) external;
function approveInvestor(uint caller, uint caller, uint seqOfLR) external;
function revokeInvestor(uint caller, uint caller, uint seqOfLR) external;
function placeInitialOffer(
uint caller, uint classOfShare, uint execHours,
uint paid, uint price, uint seqOfLR
) external;
function withdrawInitialOffer(
uint caller, uint classOfShare, uint seqOfOrder, uint seqOfLR
) external;
function placeSellOrder(
uint caller, uint seqOfClass, uint execHours, uint paid,
uint price, uint seqOfLR, bool sortFromHead
) external;
function withdrawSellOrder(uint caller, uint classOfShare, uint seqOfOrder) external;
function placeBuyOrder(uint caller, uint classOfShare, uint paid, uint price) external payable;