← 返回 Skills 市场
franckstone

Giveaway Skills

作者 Franck.S · GitHub ↗ · v0.1.0
cross-platform ✓ 安全检测通过
287
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install giveaway-skills
功能描述
Call guide and best practices for the BSC on-chain giveaway contract based on contracts/contracts/Giveaway.sol, including contract address, core method signa...
使用说明 (SKILL.md)

BSC Giveaway Contract Call Skill

1. Deployment information

  • Network: BSC (Binance Smart Chain mainnet, chainId = 56)
  • Contract file: contracts/contracts/Giveaway.sol
  • Contract address: 0xc9Db158004fEFe15633eF2Ac3C3eA209e58Db5B9
  • Main dependencies: IERC20, Ownable, ReentrancyGuard, internal TransferHelper library

Assumptions when calling:

  • You are already connected to a BSC mainnet RPC (for example https://bsc-dataseed.binance.org)
  • Account balance and gas settings are handled by the caller

2. Core enums and structs (pass as uint in calls)

DistributionType

  • 0 = AVERAGE: equal share, each claim gets amount / count
  • 1 = RANDOM: random share, a single claim is roughly in the range (0 \sim 2 imes) the average

ClaimRestriction

  • 0 = PUBLIC: public, no additional restriction
  • 1 = TOKEN_HOLDER: only addresses holding restrictionToken with balance ≥ minTokenBalance
  • 2 = WHITELIST: only whitelisted addresses can claim

GiveawayInfo

  • token: token address for the giveaway, address(0) means BNB
  • sender: creator address
  • amount: current remaining total giveaway amount in the contract (after creation fee is deducted)
  • count: current remaining claimable slots
  • distributionType: distribution type (0/1)
  • restriction: claim restriction type (0/1/2)
  • restrictionToken: restriction token address (only meaningful for TOKEN_HOLDER)
  • minTokenBalance: minimum token balance required
  • lastDate: expiration timestamp (seconds)

3. Write function cheatsheet

3.1 Create giveaway createGiveaway

Signature:

function createGiveaway(
    address token,
    uint256 amount,
    uint256 count,
    DistributionType distributionType,
    ClaimRestriction restriction,
    address restrictionToken,
    uint256 minTokenBalance,
    string memory content,
    uint256 lastDate
) public payable

Key constraints:

  • bytes(content).length \x3C 128
  • amount > 0
  • amount / count > 0
  • distributionType ∈ {0,1}
  • restriction ∈ {0,1,2}
  • If restriction == TOKEN_HOLDER (1):
    • restrictionToken != address(0)
    • minTokenBalance > 0

Fees and transfers:

  • Fee: feeAmount = (amount / 1000) * FEERATE, sent directly to FEEADDRESS
  • Actual amount entering the contract: sendAmount = amount - feeAmount
  • If token == address(0) (BNB giveaway):
    • Transaction msg.value >= amount
    • feeAmount and sendAmount are both paid in BNB
  • If token != address(0) (ERC20 giveaway):
    • Transaction msg.value == 0
    • You must first approve on-chain:
      • approve(contract, amount) (user → contract)
    • The contract internally uses safeTransferFrom to send feeAmount to FEEADDRESS and sendAmount to the contract itself

3.2 Claim giveaway claimGiveaway

function claimGiveaway(uint256 id) public nonReentrant

Internal checks:

  • giveawayInfos[id].amount != 0: giveaway exists and has remaining amount
  • Caller has not claimed yet: giveawayInfo_exist[id][msg.sender] == 0
  • Not expired: giveawayInfos[id].lastDate > block.timestamp
  • TOKEN_HOLDER: check IERC20(restrictionToken).balanceOf(msg.sender) >= minTokenBalance
  • WHITELIST: giveawayWhitelist[id][msg.sender] == true

Distribution logic:

  • AVERAGE:
    • If count == 1: send all remaining amount to the current claimer
    • Otherwise, single claim amount is sendAmount = amount / count
  • RANDOM:
    • If count == 1: also send all remaining amount
    • Otherwise:
      • randomNumber = uint8(keccak256(...)) % 100
      • sendAmount = (amount / count * 2) * randomNumber / 100

3.3 Withdraw expired giveaway withdrawExpiredGiveaway

function withdrawExpiredGiveaway(uint256 id) public nonReentrant

Constraints:

  • giveawayInfos[id].amount != 0
  • giveawayInfos[id].sender == msg.sender
  • giveawayInfos[id].lastDate \x3C block.timestamp

Withdrawal fee:

  • feeAmount = (amount / 1000) * EXPIREDRATE
  • sendAmount = amount - feeAmount
  • Transfer logic also distinguishes BNB vs ERC20

3.4 Whitelist management

function addToWhitelist(uint256 giveawayId, address[] memory addresses) public
function removeFromWhitelist(uint256 giveawayId, address[] memory addresses) public

Constraints:

  • Only the giveaway creator: giveawayInfos[giveawayId].sender == msg.sender
  • And the giveaway must be of WHITELIST type: restriction == ClaimRestriction.WHITELIST

4. Read function cheatsheet

function getGiveawayInfo(uint256 id) external view returns (GiveawayInfo memory)
function isInWhitelist(uint256 giveawayId, address user) external view returns (bool)
function canClaim(uint256 id, address user) external view returns (bool)

Key points of canClaim:

  • Returns false if amount is 0, already claimed, or block.timestamp >= lastDate
  • TOKEN_HOLDER: checks token balance
  • WHITELIST: checks whitelist
  • Otherwise returns true (PUBLIC)

5. Script / frontend usage example (ethers.js)

Assume you already have a provider / signer and have loaded the compiled ABI:

import { ethers } from "ethers";
import GiveawayAbi from "../artifacts/contracts/Giveaway.sol/Giveaway.json";

const GIVEAWAY_ADDRESS = "0xc9Db158004fEFe15633eF2Ac3C3eA209e58Db5B9";

// Create contract instance (read or write)
export function getGiveawayContract(providerOrSigner: ethers.Signer | ethers.providers.Provider) {
  return new ethers.Contract(GIVEAWAY_ADDRESS, GiveawayAbi.abi, providerOrSigner);
}

// Example: create a BNB giveaway
export async function createBnbGiveaway(
  signer: ethers.Signer,
  params: {
    amountWei: ethers.BigNumberish;
    count: number;
    distributionType: 0 | 1;
    restriction: 0 | 1 | 2;
    restrictionToken: string;
    minTokenBalance: ethers.BigNumberish;
    content: string;
    lastDate: number;
  }
) {
  const contract = getGiveawayContract(signer);
  const tx = await contract.createGiveaway(
    ethers.constants.AddressZero,
    params.amountWei,
    params.count,
    params.distributionType,
    params.restriction,
    params.restrictionToken,
    params.minTokenBalance,
    params.content,
    params.lastDate,
    { value: params.amountWei }
  );
  return tx.wait();
}

// Example: claim a giveaway
export async function claimGiveaway(signer: ethers.Signer, id: number) {
  const contract = getGiveawayContract(signer);
  const tx = await contract.claimGiveaway(id);
  return tx.wait();
}

When integrating in a frontend or script:

  • Read functions (getGiveawayInfo, canClaim, isInWhitelist) can use a provider instance;
  • Write functions (createGiveaway, claimGiveaway, withdrawExpiredGiveaway, whitelist add/remove) must use a signer with signing capability;
  • For BNB giveaways you must pass BNB equal to amount via value; for ERC20 giveaways you must approve beforehand.

7. ABI information and minimal examples

  • Full ABI source: the JSON generated after compiling contracts/contracts/Giveaway.sol in this repo (for example artifacts/.../Giveaway.json); in scripts/frontends you should generally import the abi field from that file.
  • Purpose of this section: provide a minimal ABI fragment for quick debugging or building a minimal frontend/script when you cannot directly access the compiled artifacts. It is not guaranteed to stay perfectly in sync with future contract upgrades.

7.1 Key event fragments

[
  {
    "type": "event",
    "name": "GiveawayCreated",
    "anonymous": false,
    "inputs": [
      { "indexed": false, "name": "id", "type": "uint256" },
      { "indexed": false, "name": "token", "type": "address" },
      { "indexed": false, "name": "sender", "type": "address" },
      { "indexed": false, "name": "amount", "type": "uint256" },
      { "indexed": false, "name": "count", "type": "uint256" },
      { "indexed": false, "name": "distributionType", "type": "uint8" },
      { "indexed": false, "name": "restriction", "type": "uint8" },
      { "indexed": false, "name": "restrictionToken", "type": "address" },
      { "indexed": false, "name": "minTokenBalance", "type": "uint256" },
      { "indexed": false, "name": "content", "type": "string" },
      { "indexed": false, "name": "lastDate", "type": "uint256" }
    ]
  },
  {
    "type": "event",
    "name": "GiveawayClaimed",
    "anonymous": false,
    "inputs": [
      { "indexed": false, "name": "id", "type": "uint256" },
      { "indexed": false, "name": "sender", "type": "address" },
      { "indexed": false, "name": "count", "type": "uint256" },
      { "indexed": false, "name": "amount", "type": "uint256" }
    ]
  },
  {
    "type": "event",
    "name": "GiveawayWithdrawn",
    "anonymous": false,
    "inputs": [
      { "indexed": false, "name": "id", "type": "uint256" }
    ]
  },
  {
    "type": "event",
    "name": "WhitelistAdded",
    "anonymous": false,
    "inputs": [
      { "indexed": true, "name": "giveawayId", "type": "uint256" },
      { "indexed": false, "name": "addresses", "type": "address[]" }
    ]
  },
  {
    "type": "event",
    "name": "WhitelistRemoved",
    "anonymous": false,
    "inputs": [
      { "indexed": true, "name": "giveawayId", "type": "uint256" },
      { "indexed": false, "name": "addresses", "type": "address[]" }
    ]
  }
]

7.2 Common function fragments

Only the most common read/write function signatures are listed below, to make it easy to construct ethers.Contract / web3.eth.Contract. For the full ABI, always refer to the build artifacts.

[
  {
    "type": "function",
    "stateMutability": "payable",
    "name": "createGiveaway",
    "inputs": [
      { "name": "token", "type": "address" },
      { "name": "amount", "type": "uint256" },
      { "name": "count", "type": "uint256" },
      { "name": "distributionType", "type": "uint8" },
      { "name": "restriction", "type": "uint8" },
      { "name": "restrictionToken", "type": "address" },
      { "name": "minTokenBalance", "type": "uint256" },
      { "name": "content", "type": "string" },
      { "name": "lastDate", "type": "uint256" }
    ],
    "outputs": []
  },
  {
    "type": "function",
    "stateMutability": "nonpayable",
    "name": "claimGiveaway",
    "inputs": [
      { "name": "id", "type": "uint256" }
    ],
    "outputs": []
  },
  {
    "type": "function",
    "stateMutability": "nonpayable",
    "name": "withdrawExpiredGiveaway",
    "inputs": [
      { "name": "id", "type": "uint256" }
    ],
    "outputs": []
  },
  {
    "type": "function",
    "stateMutability": "nonpayable",
    "name": "addToWhitelist",
    "inputs": [
      { "name": "giveawayId", "type": "uint256" },
      { "name": "addresses", "type": "address[]" }
    ],
    "outputs": []
  },
  {
    "type": "function",
    "stateMutability": "nonpayable",
    "name": "removeFromWhitelist",
    "inputs": [
      { "name": "giveawayId", "type": "uint256" },
      { "name": "addresses", "type": "address[]" }
    ],
    "outputs": []
  },
  {
    "type": "function",
    "stateMutability": "view",
    "name": "getGiveawayInfo",
    "inputs": [
      { "name": "id", "type": "uint256" }
    ],
    "outputs": [
      {
        "components": [
          { "name": "token", "type": "address" },
          { "name": "sender", "type": "address" },
          { "name": "amount", "type": "uint256" },
          { "name": "count", "type": "uint256" },
          { "name": "distributionType", "type": "uint8" },
          { "name": "restriction", "type": "uint8" },
          { "name": "restrictionToken", "type": "address" },
          { "name": "minTokenBalance", "type": "uint256" },
          { "name": "lastDate", "type": "uint256" }
        ],
        "type": "tuple"
      }
    ]
  },
  {
    "type": "function",
    "stateMutability": "view",
    "name": "canClaim",
    "inputs": [
      { "name": "id", "type": "uint256" },
      { "name": "user", "type": "address" }
    ],
    "outputs": [
      { "type": "bool" }
    ]
  },
  {
    "type": "function",
    "stateMutability": "view",
    "name": "isInWhitelist",
    "inputs": [
      { "name": "giveawayId", "type": "uint256" },
      { "name": "user", "type": "address" }
    ],
    "outputs": [
      { "type": "bool" }
    ]
  }
]

The fragments above can be combined with the TypeScript example earlier, for example:

const abi = [...eventsFragment, ...functionsFragment];
const contract = new ethers.Contract(GIVEAWAY_ADDRESS, abi, signerOrProvider);

6. Relationship with existing giveaway-protocol skill

  • giveaway-protocol focuses more on the protocol-level description (enum semantics, logical constraints, general call conventions);
  • giveaway-skills is specifically about this concrete contract deployed on BSC mainnet (fixed contract address + specific network info + call examples).

When you need “the contract address and direct on-chain interaction”, you should prefer this skill.
If you need more complete error descriptions or protocol details, you can also refer to giveaway-protocol’s reference.md.

安全使用建议
This skill is an instruction-only guide and appears internally consistent, but follow these precautions before using it: 1) Verify the contract address and source on BscScan (confirm the on-chain bytecode and verified source match) before sending funds. 2) Review the actual Giveaway.sol source (FEERATE, EXPIREDRATE, transfer behavior) to understand fees and edge cases. 3) Never paste private keys into untrusted UIs — use a hardware wallet or signer abstraction; avoid granting any agent or interface direct access to your private keys. 4) When using ERC-20 giveaways, approve only the exact amount required and consider allowance limits to reduce risk. 5) Test interactions on a BSC testnet or with minimal amounts first. 6) Be cautious about the RANDOM distribution mode (it can send variable amounts) and the contract’s handling of fees and safe transfers. 7) Since the skill is instruction-only and does not itself perform transactions, ensure the code you run (ABI/artifacts and provider/signer setup) comes from trusted sources.
功能分析
Type: OpenClaw Skill Name: giveaway-skills Version: 0.1.0 The skill bundle is a technical reference for interacting with a specific giveaway smart contract on the Binance Smart Chain (0xc9Db158004fEFe15633eF2Ac3C3eA209e58Db5B9). SKILL.md contains standard documentation, ABI fragments, and ethers.js code examples for creating and claiming giveaways, with no evidence of malicious intent, prompt injection, or data exfiltration.
能力评估
Purpose & Capability
The name/description (BSC giveaway contract call guide) matches the SKILL.md content: contract address, function signatures, parameter meanings, and ethers.js usage. The skill does not request unrelated permissions, binaries, or credentials.
Instruction Scope
SKILL.md stays within the scope of calling and interacting with the specified contract (create/claim/withdraw/whitelist/read). It assumes a provider/signer and compiled ABI artifacts, which is appropriate for the described tasks. It does not instruct reading system files or exporting unrelated data.
Install Mechanism
There is no install spec; the skill is instruction-only and therefore does not write code to disk or download external packages. This is the lowest-risk install model.
Credentials
The SKILL.md requests no environment variables or credentials. Operational use will require an RPC endpoint and a signer (private key or wallet) provided externally — this is expected but sensitive. The skill does not ask for unrelated credentials.
Persistence & Privilege
always is false and the skill does not request persistent system privileges or modify other skills' configs. The agent may invoke the skill autonomously by default, but that is the platform norm and not a specific risk here.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install giveaway-skills
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /giveaway-skills 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v0.1.0
Initial release of BSC Giveaway Contract Call Skill. - Provides call guide and best practices for the Giveaway.sol contract on BSC mainnet. - Documents core function signatures, parameters, method conventions, and contract address. - Explains setup for creating and claiming giveaways, managing whitelists, and withdrawing expired giveaways. - Includes usage examples for integrating with scripts and frontends using ethers.js. - Offers concise overviews of distribution types, claim restrictions, and contract data structures. - Lists minimal ABI information and guidance for both ERC20 and BNB giveaways.
元数据
Slug giveaway-skills
版本 0.1.0
许可证
累计安装 0
当前安装数 0
历史版本数 1
常见问题

Giveaway Skills 是什么?

Call guide and best practices for the BSC on-chain giveaway contract based on contracts/contracts/Giveaway.sol, including contract address, core method signa... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 287 次。

如何安装 Giveaway Skills?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install giveaway-skills」即可一键安装,无需额外配置。

Giveaway Skills 是免费的吗?

是的,Giveaway Skills 完全免费(开源免费),可自由下载、安装和使用。

Giveaway Skills 支持哪些平台?

Giveaway Skills 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Giveaway Skills?

由 Franck.S(@franckstone)开发并维护,当前版本 v0.1.0。

💬 留言讨论