Skip to content

Instantly share code, notes, and snippets.

@Kouhei-Takagi
Last active March 20, 2026 11:31
Show Gist options
  • Select an option

  • Save Kouhei-Takagi/51ac1d3ed91144d28a47bc3566a9d3f4 to your computer and use it in GitHub Desktop.

Select an option

Save Kouhei-Takagi/51ac1d3ed91144d28a47bc3566a9d3f4 to your computer and use it in GitHub Desktop.
BPS Coin v0.1: The 500-Year Torch (Prototype)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/**
* @title BPS Coin: Time Decay Prototype (v0.1)
* @author Kouhei Takagi & Gemini
* @notice 「500年でゼロになる」というエントロピーをハードコードした通貨。
* 独占を物理的に不可能にし、価値を未来へと循環させるための救助ロープ。
* https://www.creatingfavoriteopinions.com
*/
contract BPSCoin is ERC20 {
// 各アドレスが最後に「価値を更新(送受信)」した時間を記録
mapping(address => uint256) public lastUpdated;
// デフォルトの寿命設定:500年(テスト時は 20 minutes 等に変更可能)
uint256 public constant MAX_LIFESPAN = 500 * 365 days;
constructor() ERC20("Blue Planet System Coin", "BPS") {
// 初期発行枚数(例:100万枚)
_mint(msg.sender, 1000000 * 10**18);
lastUpdated[msg.sender] = block.timestamp;
}
/**
* @dev 時間の経過による「現在の実質価値」を計算する
* 線形減衰モデル:残り時間に応じて価値が直線的に減少する
*/
function getCurrentValue(address account) public view returns (uint256) {
uint256 rawBalance = balanceOf(account);
if (rawBalance == 0) return 0;
uint256 timePassed = block.timestamp - lastUpdated[account];
if (timePassed >= MAX_LIFESPAN) return 0;
// 公式: 現在の価値 = 額面 × (残り寿命 / 全寿命)
return (rawBalance * (MAX_LIFESPAN - timePassed)) / MAX_LIFESPAN;
}
/**
* @dev 送金処理。実行時に自動的に「腐った分」を焼き捨て(Burn)、
* 受け取り側の寿命タイマーをリセットすることで「循環」を生む。
*/
function transfer(address to, uint256 amount) public override returns (bool) {
uint256 currentValue = getCurrentValue(msg.sender);
require(currentValue >= amount, "Not enough viable BPS: Value has decayed.");
// 1. 蓄積されていた「腐った分」を強制的にBurn(消滅)させる
uint256 decayAmount = balanceOf(msg.sender) - currentValue;
if (decayAmount > 0) {
_burn(msg.sender, decayAmount);
}
// 2. 新鮮な価値だけを送金
super.transfer(to, amount);
// 3. 両者のタイマーをリセット(新陳代謝)
lastUpdated[to] = block.timestamp;
lastUpdated[msg.sender] = block.timestamp;
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment