CCIP Number | 007 |
---|---|
Title | CityCoins Auth |
Author(s) | Jason Schrader jason@joinfreehold.com |
Consideration | Technical |
Type | Standard |
Status | Ratified |
Created | 2022-03-16 |
License | BSD-2-Clause |
The Stacks blockchain is a Layer 1 blockchain connected to Bitcoin, in which miners spend Bitcoin to bid for and win a fixed amount of Stacks tokens. Stackers have the option to lock up Stacks tokens for a specified amount of time, and in turn, receive a portion of the Bitcoin spent by miners proportionate to the amount Stacked1.
Taking this concept a level further, a new token (a "CityCoin") is created on the Stacks blockchain, following the SIP-010 fungible token standard2, such that CityCoins can be mined and Stacked per the methods stated above except a portion of the miner's bid would be redirected to the city's wallet overseen by a trusted third party custodian.
CityCoins leverage similar properties from the Proof of Transfer (PoX) consensus mechanism3 of the Stacks blockchain, programmed through a smart contract in Clarity.
This proposal describes the protected functions used in the auth contract for a CityCoin.
The auth contract for a CityCoin contains protected functions that allow the city wallet or a backup list of approvers to authorize:
- an update to the city wallet address, in case the custody address is changed
- an upgrade to the core contract, replacing the current core contract with a new one
- an update to the token URI, which specifies the off-chain location of the CityCoin token data
The city wallet is a 2-of-3 multisignature wallet, and requires 2-of-3 approval before any of the protected functions can be used.
An additional backup 3-of-5 approval method is instantiated among independent entities before any of the protected functions can be used.
The auth contract allows the city wallet to call any of the protected functions once the required number of signatures have been collected.
The backup approver list must submit a job through a specific flow designed to allow approvers to:
- create a job for approval with specific parameters
- city wallet update must have a principal value for
newCityWallet
- core contract upgrade must have principal values for
oldContract
andnewContract
- replacing approvers must have principal values for
oldApprover
andnewApprover
- city wallet update must have a principal value for
- cast votes on a job for approval/disapproval
- reverse votes on a job for approval/disapproval
- execute a specific jobs if the approval threshold is met
- city wallet update uses
execute-set-city-wallet-job
- core contract upgrade uses
execute-upgrade-core-contract-job
- replacing approvers uses
execute-replace-approver-job
- city wallet update uses
Within the auth contract are variables to track information across two categories.
Related to core contracts:
- a map of core contracts and their state
- the current active core contract principal
- the city wallet address
Related to jobs and approvals:
- a map of approvers and their state
- the required approvals for jobs
- the ID of the last job created
- job information and status
- votes by approvers for each job
- a list of the approver addresses
- argument details by name and ID
Core contracts states are defined below:
State | uint | Description |
---|---|---|
STATE_DEPLOYED | u0 | Core contract deployed but not activated |
STATE_ACTIVE | u1 | Core contract activated, mining/stacking available |
STATE_INACTIVE | u2 | Core contract shutdown, mining/stacking unavailable |
When the set-city-wallet
function is called, the contract then:
- verifies the caller is the city wallet principal
- verifies the core contract is the active core contract
- sets the city wallet variable in auth and the active core contract
When the execute-set-city-wallet-job
function is called, the contract then:
- verifies the correct job arguments are found
- verifies the caller is in the approvers map
- verifies the core contract is the active core contract
- sets the city wallet variable in auth and the active core contract
- marks the job as executed
- verifies the job ID is found
- verifies the job is active
- verifies the job has the required approvals
- verifies the auth contract is marking the job as executed
- verifies job was not already executed
- updates the job status to executed
When the upgrade-core-contract
function is called, the contract then:
- verifies the old core contract is in the core contract map
- verifies the old and new core contract are not the same
- verifies the caller is the city wallet principal
- updates the core contract states
- old contract is set to STATE_INACTIVE
- new contract is set to STATE_DEPLOYED
- the active contract variable is updated to the new contract principal
- calls the
shutdown-contract
in the old core contract - sets the city wallet variable in the new core contract
When the execute-upgrade-core-contract-job
function is called, the contract then:
- verifies the correct job arguments are found
- verifies the old core contract is in the core contract map
- verifies the caller is in the approvers map
- verifies the old and new core contract are not the same
- updates the core contract states
- old contract is set to STATE_INACTIVE
- new contract is set to STATE_DEPLOYED
- the active contract variable is updated to the new contract principal
- calls the
shutdown-contract
in the old core contract - sets the city wallet variable in the new core contract
- marks the job as executed
- verifies the job ID is found
- verifies the job is active
- verifies the job has the required approvals
- verifies the auth contract is marking the job as executed
- verifies job was not already executed
- updates the job status to executed
When the set-token-uri
function is called, the contract then:
- verifies the caller is the city wallet principal
- updates the token URI variable in the token contract
When the execute-replace-approver-job
function is called, the contract then:
- verifies the correct job arguments are found
- verifies the caller is in the approvers map
- disable the old approver address
- add and enable the new approver address
- marks the job as executed
- verifies the job ID is found
- verifies the job is active
- verifies the job has the required approvals
- verifies the auth contract is marking the job as executed
- verifies job was not already executed
- updates the job status to executed
None, this is the initial implementation.
None, this is the initial implementation.
MiamiCoin Contracts:
miamicoin-auth
deployed on the Stacks mainnet4, implementing:- the
upgrade-core-contract
function on lines 423-452 - the
execute-upgrade-core-contract-job
function on lines 454-485 - the
set-city-wallet
function on lines 497-510 - the
execute-set-city-wallet-job
function on lines 512-525 - the
set-token-uri
function on lines 534-540 - the
execute-replace-approver-job
function on lines 544-555
- the
NewYorkCityCoin Contracts:
newyorkcitycoin-auth
deployed on the Stacks mainnet5, implementing:- the
upgrade-core-contract
function on lines 424-453 - the
execute-upgrade-core-contract-job
function on lines 455-486 - the
set-city-wallet
function on lines 498-511 - the
execute-set-city-wallet-job
function on lines 513-526 - the
set-token-uri
function on lines 535-541 - the
execute-replace-approver-job
function on lines 545-556
- the
Footnotes
-
https://github.com/stacksgov/sips/blob/main/sips/sip-010/sip-010-fungible-token-standard.md ↩
-
https://docs.stacks.co/understand-stacks/proof-of-transfer ↩
-
https://explorer.stacks.co/txid/SP466FNC0P7JWTNM2R9T199QRZN1MYEDTAR0KP27.miamicoin-auth?chain=mainnet ↩
-
https://explorer.stacks.co/txid/SP2H8PY27SEZ03MWRKS5XABZYQN17ETGQS3527SA5.newyorkcitycoin-auth?chain=mainnet ↩