This smart contract enables transparent, on-chain prize distribution on the Magi Network. Split prizes among random winners or predefined recipients with flexible multi-asset support.
We highly encourage you to use okinoko.io for interacting with this smart contract. There is a nice UI where you can make no mistakes.
- Random Winner Selection – Pick winners randomly from a participant pool
- Defined Distribution – Distribute prizes to specific recipients with custom shares
- Multi-Asset Support – Distribute HIVE and HBD simultaneously to different winners
- Per-Winner Asset Allocation – Each winner can receive different assets with custom percentages
- Winner Messages – Include personalized memos with
{n}or{nth}position placeholders - L1/L2 Transfer Flexibility – Choose between Magi transfers (default) or L1 withdrawals to Hive blockchain
- Gas Efficient – Fixed-point arithmetic, transaction-scoped caching, events instead of state persistence
Randomly select winners from a participant pool and distribute prizes with equal or custom shares per asset.
Payload Format:
winnerCount|participants|assetShares|message|transferToL1
Parameters:
winnerCount– Number of winners to select (1-100)participants– Participant addresses separated by semicolon, comma, or space- Full format:
hive:alice;hive:bob;hive:charlie - Short format:
@alice @bob @charlie(automatically converted tohive:format) - Mixed delimiters:
@alice,hive:bob @charlie;hive:dave
- Full format:
assetShares– (Optional) Semicolon-separated asset share groups for each winner- Single asset:
50#hive;30#hive;20#hive - Multi-asset:
(50#hive,60#hbd);(30#hive,40#hbd);(20#hive) - Leave empty for equal shares across all provided assets
- Single asset:
message– (Optional) Winner message with{n}or{nth}placeholdertransferToL1– (Optional) Transfer to L1 (true,1, oryesto enable; defaults tofalse)
Requirements:
- At least one
transfer.allowintent with HIVE or HBD - Winner count must not exceed participant count or max winners (100)
- Asset shares must sum to 100% per asset
- Asset share groups must match winner count if provided
Returns:
"prize distributed to random winners"
Examples:
# Equal shares among 3 random winners (auto-distributes all provided assets equally)
3|hive:alice;hive:bob;hive:charlie;hive:dave;hive:eve
# Custom HIVE shares with message
3|hive:alice;hive:bob;hive:charlie;hive:dave|50#hive;30#hive;20#hive|Winner #{n} selected!
# Multi-asset: Winner 1 gets 50% HIVE + 60% HBD, Winner 2 gets 30% HIVE + 40% HBD, Winner 3 gets 20% HIVE
3|hive:alice;hive:bob;hive:charlie;hive:dave|(50#hive,60#hbd);(30#hive,40#hbd);(20#hive)
# Transfer to L1 with equal shares
3|hive:alice;hive:bob;hive:charlie;hive:dave;hive:eve|||true
# Custom shares with message and L1 transfer
3|hive:alice;hive:bob;hive:charlie;hive:dave|50#hive;30#hive;20#hive|Winner #{n}|true
# Using @username format with space delimiter
3|@alice @bob @charlie @dave @eve
Distribute prizes to predefined winners with custom share percentages or fixed amounts per asset.
Payload Format:
winner1#assetShares;winner2#assetShares|message|transferToL1
Parameters:
winners– Semicolon-separated winner entries (addresses support@usernameformat)- Percentage mode:
address#percentage#asset(e.g.,hive:alice#50#hiveor@alice#50#hive) - Fixed amount mode:
address#amount#asset#fixed(e.g.,hive:alice#5.000#hive#fixedor@alice#5.000#hive#fixed) - Multi-asset:
address#(share#asset,share#asset)oraddress#(amount#asset#fixed,amount#asset#fixed)
- Percentage mode:
message– (Optional) Winner message with{n}or{nth}placeholdertransferToL1– (Optional) Transfer to L1 (true,1, oryesto enable; defaults tofalse)
Distribution Modes:
- Percentage Mode (default): Share percentages must sum to 100% per asset
- Fixed Amount Mode: Specify exact amounts; total must not exceed transfer intent limit
- Cannot mix modes: Each asset must use either percentage OR fixed mode, not both
Requirements:
- At least one
transfer.allowintent with HIVE or HBD - Percentage mode: Shares must sum to 100% per asset
- Fixed mode: Total amounts must not exceed available funds
- Maximum 100 winners
- Each winner must have at least one asset share
Returns:
"prize distributed to defined winners"
Examples:
# Percentage mode (shares sum to 100%)
hive:alice#50#hive;hive:bob#30#hive;hive:charlie#20#hive
# Fixed amount mode (exact amounts)
hive:alice#5.000#hive#fixed;hive:bob#3.000#hive#fixed;hive:charlie#2.000#hive#fixed
# With winner message
hive:alice#60#hive;hive:bob#40#hive|Prize winner #{n} - congratulations!
# Multi-asset percentage: alice gets 50% HIVE + 60% HBD, bob gets 30% HIVE + 40% HBD
hive:alice#(50#hive,60#hbd);hive:bob#(30#hive,40#hbd);hive:charlie#20#hive
# Multi-asset fixed amounts
hive:alice#(5.000#hive#fixed,3.000#hbd#fixed);hive:bob#(3.000#hive#fixed,2.000#hbd#fixed)
# HBD only with fixed amounts
hive:alice#7.000#hbd#fixed;hive:bob#3.000#hbd#fixed
# With L1 transfer enabled
hive:alice#50#hive;hive:bob#50#hive||true
# Fixed amounts with message and L1 transfer
hive:alice#5.000#hive#fixed;hive:bob#3.000#hive#fixed|You won {nth} place!|true
# Using @username format
@alice#50#hive;@bob#30#hive;@charlie#20#hive
By default, prize distributions use L2 transfers (sdk.HiveTransfer), which keep assets within the Magi Network for faster, gas-efficient transactions.
The optional transferToL1 parameter enables L1 withdrawals (sdk.HiveWithdraw), which transfer assets back to the Hive Layer 1 blockchain. This is useful when winners need their prizes on the main Hive chain rather than the L2.
When to use L1 transfer:
- Winners prefer assets on Hive L1
- Prizes will be used outside the Magi Network
When to use L2 transfer (default):
- Winners will use prizes within the Magi Network
- Faster distribution is desired
- Attract users to use/learn about Magi
Accepted values:
true,1,yes(case-insensitive) → Enable L1 transferfalse,0,no, or empty → L2 transfer (default)
Functions require transfer.allow intents to authorize fund transfers:
// Single asset
{
"type": "transfer.allow",
"args": {
"limit": "10.000",
"token": "hive"
}
}
// Multi-asset distribution
[
{
"type": "transfer.allow",
"args": { "limit": "10.000", "token": "hive" }
},
{
"type": "transfer.allow",
"args": { "limit": "20.000", "token": "hbd" }
}
]The contract emits two types of events for indexing:
Logged once per asset per distribution with full details.
Format:
pd|type:<type>|by:<creator>|total:<amount>|asset:<asset>|winners:<count>|seed:<seed>|data:<winners>
Fields:
type–randomordefinedby– Creator addresstotal– Total amount distributed (3 decimal places)asset– Asset type (hiveorhbd)winners– Number of winners for this assetseed– Random seed (empty for defined distributions)data– Semicolon-separatedaddress:amount:shareentries
Example:
pd|type:random|by:hive:alice|total:10.000|asset:hive|winners:3|seed:1234567890|data:hive:bob:3.333:33.33;hive:charlie:3.333:33.33;hive:dave:3.334:33.34
Logged once per winner for each individual transfer.
Format:
pp|to:<winner>|amount:<amount>|asset:<asset>|memo:<message>
Fields:
to– Winner addressamount– Prize amount (3 decimal places)asset– Asset typememo– (Optional) Winner message (only if provided)
Example:
pp|to:hive:bob|amount:5.000|asset:hive|memo:Congrats! You won place 1!
- Max Winners: 100 per distribution (prevents gas exhaustion)
- Supported Assets: HIVE and HBD only
- Share Precision: Shares must sum to 100% per asset (±0.1% tolerance for rounding)
- Address Format: Must use
hive:usernameformat - Delimiter: Use
#for separating values - Winner Message: Maximum 100 characters (prevents storage bloat)
Function: split_prize_random
Payload: 5|hive:alice;hive:bob;hive:charlie;hive:dave;hive:eve;hive:frank
Intent: transfer.allow with 50.000 HIVE
Result: 5 winners selected randomly, each receives 10.000 HIVE
Function: split_prize_defined
Payload: hive:winner1#70#hive;hive:winner2#20#hive;hive:winner3#10#hive|Winner #{n}!
Intent: transfer.allow with 100.000 HIVE
Result:
- winner1: 70.000 HIVE with memo "Winner #1!"
- winner2: 20.000 HIVE with memo "Winner #2!"
- winner3: 10.000 HIVE with memo "Winner #3!"
Function: split_prize_defined
Payload: hive:alice#(50#hive,60#hbd);hive:bob#(30#hive,40#hbd);hive:charlie#(20#hive)
Intents:
- transfer.allow with 10.000 HIVE
- transfer.allow with 5.000 HBD
Result:
- alice: 5.000 HIVE + 3.000 HBD
- bob: 3.000 HIVE + 2.000 HBD
- charlie: 2.000 HIVE
Function: split_prize_random
Payload: 3|hive:a;hive:b;hive:c;hive:d|(50#hive,60#hbd);(30#hive,40#hbd);(20#hive)
Intents:
- transfer.allow with 10.000 HIVE
- transfer.allow with 5.000 HBD
Result:
- Random winner 1: 5.000 HIVE + 3.000 HBD
- Random winner 2: 3.000 HIVE + 2.000 HBD
- Random winner 3: 2.000 HIVE
Function: split_prize_defined
Payload: hive:alice#7.500#hive#fixed;hive:bob#5.000#hive#fixed;hive:charlie#2.500#hive#fixed
Intent: transfer.allow with 20.000 HIVE
Result:
- alice: exactly 7.500 HIVE
- bob: exactly 5.000 HIVE
- charlie: exactly 2.500 HIVE
- Remaining 5.000 HIVE stays with sender (not distributed)
All operations are highly optimized:
| Function | Typical Gas Usage | Notes |
|---|---|---|
split_prize_random |
~100-500 RC | Scales with winner count |
split_prize_defined |
~100-300 RC | Scales with winner count |
Actual costs vary based on participants, winner count, asset count, and complexity
- Always verify participant/winner addresses before submitting
- Parentheses
()group multiple assets for a single winner:(50#hive,60#hbd) - Percentage mode (default): Shares are percentages (0-100), must sum to 100% per asset
- Fixed mode: Add
#fixedto specify exact amounts (e.g.,5.000#hive#fixed) - Cannot mix percentage and fixed modes for the same asset
- In percentage mode, the last winner gets the remainder to handle rounding precision
- In fixed mode, unused funds remain with the sender (not distributed)
- Random selection is deterministic based on transaction hash for verifiability
- If no asset shares are provided for random distribution, all assets are distributed equally