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
0when send from an embedded address. - The base plasma is
AccountBlockBasePlasmawhen receiving a transaction. - The base plasma is
(blockDataByteLength * ABByteDataPlasma) + AccountBlockBasePlasmawhen 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