The following explanation is an attempt to give some insight in the current implementation of PoW and Plasma.
Transaction
When preparing a transaction, a call is made to the getRequiredPoWForAccountBlock
JSON-RPC method.
The method accepts one argument containing the transaction Address
, BlockType
, ToAddress
and Data
and returns the AvailablePlasma
, BasePlasma
and RequiredDifficulty
.
The following example shows a JSON-RPC request and response for calling the Pillar.CollectReward
embedded method.
Request
{
"jsonrpc": "2.0",
"id": 5,
"method": "embedded.plasma.getRequiredPoWForAccountBlock",
"params": [
{
"address": "z1qqjnwjjpnue8xmmpanz6csze6tcmtzzdtfsww7",
"blockType": 2,
"toAddress": "z1qxemdeddedxpyllarxxxxxxxxxxxxxxxsy3fmg",
"data": "r0PT8A=="
}
]
}
Response
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"availablePlasma": 0,
"basePlasma": 52500,
"requiredDifficulty": 78750000
}
}
PoW is calculated using a SHA3-256 hash (made by combining the bytes of the Address
and FrontierHashBlock
) and the RequiredDifficulty
. The PoW is only undertaken when RequiredDifficulty
is not 0
; otherwise a nonce of 0000000000000000
is used.
When the nonce is set, the transaction is hashed, signed and published to the network.
PoW Calculation
The getRequiredPoWForAccountBlock
JSON-RPC method does three things:
- Calculate available plasma
- Calculate base plasma
- Calculate difficulty
Calculate available plasma
The available plasma is calculated by using the total amount of plasma available minus used plasma by unconfirmed blocks. Plasma equals to fusedPlasma - plasmaUsedByUnconfirmedBlocks
.
Calculate base plasma
The base plasma is calculated depending on four different scenarios.
- The base plasma is
0
when send from an embedded address. - The base plasma is
AccountBlockBasePlasma
when receiving a transaction. - The base plasma is
(blockDataByteLength * ABByteDataPlasma) + AccountBlockBasePlasma
when sending to a non embedded address. - The base plasma is calculated according to the PlasmaTable when interacting with an embedded contract method.
Calculate difficulty
The required difficulty is 0
when the available plasma is bigger than the base plasma; otherwise the remaining required plasma is used to caluclate the difficulty by multiplying it by PoWDifficultyPerPlasma (basePlasma - availablePlasma) * PoWDifficultyPerPlasma
. The result can never be bigger than MaxPoWPlasmaForAccountBlock
.
PlasmaTable
The following plasma table shows the required plasma for each embedded contract method.
The values presented below are based on the AcceleratorSpork.
EmbeddedContract | Method | Plasma |
---|---|---|
Accellerator | CreateProject | EmbeddedSimple |
Accellerator | AddPhase | EmbeddedSimple |
Accellerator | UpdateEmbeddedAccelerator | EmbeddedWWithdraw |
Accellerator | UpdatePhase | EmbeddedSimple |
Common | CollectReward [1] | EmbeddedSimple |
Common | DepositQsr | EmbeddedSimple |
Common | WithdrawQsr | EmbeddedSimple |
Common | Donate | EmbeddedSimple |
Common | VoteByName | EmbeddedSimple |
Common | VoteByProdAddress | EmbeddedSimple |
Liquidity | UpdateEmbeddedLiquidity | EmbeddedSimple |
Liquidity | Fund | EmbeddedSimple |
Liquidity | BurnZnn | EmbeddedSimple |
Pillars | Register [2] | 2 * EmbeddedSimple |
Pillars | LegacyRegister [2] | 2 * EmbeddedSimple |
Pillars | Revoke | EmbeddedWWithdraw |
Pillars | UpdatePillar | EmbeddedSimple |
Pillars | Delegate | EmbeddedSimple |
Pillars | Undelegate | EmbeddedSimple |
Pillars | UpdateEmbeddedPillar | EmbeddedSimple |
Plasma | Fuse | EmbeddedSimple |
Plasma | CancelFuse | EmbeddedWWithdraw |
Sentinel | RegisterSentinel | EmbeddedSimple |
Sentinel | RevokeSentinel | EmbeddedWDoubleWithdraw |
Sentinel | UpdateEmbeddedSentinel | EmbeddedSimple |
Spork | CreateSpork | EmbeddedSimple |
Spork | ActivateSpork | EmbeddedSimple |
Stake | Stake | EmbeddedSimple |
Stake | CancelStake | EmbeddedWWithdraw |
Stake | UpdateEmbeddedState | EmbeddedSimple |
Swap | SwapRetrieveAssets | EmbeddedWDoubleWithdraw |
Token | Issue | EmbeddedWWithdraw |
Token | Mint | EmbeddedWWithdraw |
Token | Burn | EmbeddedSimple |
Token | UpdateToken | EmbeddedSimple |
- CollectReward for Pillar, Sentinel and Stake
- Include burn tx
Constants
AccountBlockBasePlasma = 21000
ABByteDataPlasma = 68
EmbeddedSimplePlasma = 2.5 * AccountBlockBasePlasma
EmbeddedWResponse = 3.5 * AccountBlockBasePlasma
EmbeddedWDoubleResponse = 4.5 * AccountBlockBasePlasma
NumFusionUnitsForBasePlasma = 10
PlasmaPerFusionUnit = AccountBlockBasePlasma / NumFusionUnitsForBasePlasma
CostPerFusionUnit = 100000000
PoWDifficultyPerPlasma = 1500
// MaxDataLength defines limit of account-block data to 16Kb
MaxDataLength = 1024 * 16
// MaxPlasmaForAccountBlock defines max available plasma for an account block.
MaxPlasmaForAccountBlock = MaxFusionPlasmaForAccount
MaxPoWPlasmaForAccountBlock = EmbeddedWDoubleResponse
MaxDifficultyForAccountBlock = MaxPoWPlasmaForAccountBlock * PoWDifficultyPerPlasma
// MaxFusionUnitsPerAccount limits each account to a maximum of 5000 fusion units.
// All units above this will not increase the maximum plasma.
MaxFusionUnitsPerAccount = 5000
MaxFusionPlasmaForAccount = MaxFusionUnitsPerAccount * PlasmaPerFusionUnit
MaxFussedAmountForAccount = CostPerFusionUnit * MaxFusionUnitsPerAccount