首页 / 教程文章 / 网络传媒WordPress柔性广告智能合约插件开发指南

网络传媒WordPress柔性广告智能合约插件开发指南

网络传媒WordPress柔性广告智能合约插件开发指南

概述

在当今数字化媒体时代,网络传媒平台面临着广告管理复杂、交易不透明、结算效率低下等挑战。本文将详细介绍如何开发一个基于WordPress的柔性广告智能合约插件,通过区块链技术实现广告交易的自动化、透明化和智能化管理。

技术架构设计

系统架构概览

本插件采用三层架构设计:

  1. 表示层:WordPress前端界面
  2. 业务逻辑层:PHP智能合约管理模块
  3. 区块链层:以太坊智能合约交互

开发环境配置

<?php
/**
 * WordPress柔性广告智能合约插件 - 主文件
 * Plugin Name: Flexible Ad Smart Contract
 * Description: 基于区块链的智能广告合约管理插件
 * Version: 1.0.0
 * Author: 网络传媒技术团队
 */

// 防止直接访问
if (!defined('ABSPATH')) {
    exit;
}

// 定义插件常量
define('FASC_VERSION', '1.0.0');
define('FASC_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FASC_PLUGIN_URL', plugin_dir_url(__FILE__));

// 引入必要文件
require_once FASC_PLUGIN_DIR . 'includes/class-smart-contract-manager.php';
require_once FASC_PLUGIN_DIR . 'includes/class-ad-campaign.php';
require_once FASC_PLUGIN_DIR . 'includes/class-blockchain-connector.php';
?>

智能合约开发

以太坊智能合约代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title FlexibleAdContract
 * @dev 柔性广告智能合约,管理广告展示、点击和结算
 */
contract FlexibleAdContract {
    
    // 合约所有者
    address public owner;
    
    // 广告活动结构
    struct AdCampaign {
        uint256 id;
        address advertiser;
        string title;
        uint256 budget;
        uint256 spent;
        uint256 cpc; // 每次点击成本(wei)
        bool isActive;
        uint256 startTime;
        uint256 endTime;
        uint256 maxImpressions;
        uint256 impressionCount;
        uint256 clickCount;
    }
    
    // 事件定义
    event CampaignCreated(uint256 campaignId, address advertiser);
    event AdDisplayed(uint256 campaignId, uint256 impressionId);
    event AdClicked(uint256 campaignId, uint256 clickId, address viewer);
    event PaymentProcessed(uint256 campaignId, uint256 amount);
    
    // 存储映射
    mapping(uint256 => AdCampaign) public campaigns;
    mapping(uint256 => mapping(address => bool)) public hasClicked;
    uint256 public campaignCounter;
    
    // 修饰符:仅所有者
    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this");
        _;
    }
    
    // 构造函数
    constructor() {
        owner = msg.sender;
        campaignCounter = 0;
    }
    
    /**
     * @dev 创建新的广告活动
     * @param _title 广告标题
     * @param _budget 总预算(wei)
     * @param _cpc 每次点击成本
     * @param _maxImpressions 最大展示次数
     * @param _duration 活动持续时间(秒)
     */
    function createCampaign(
        string memory _title,
        uint256 _budget,
        uint256 _cpc,
        uint256 _maxImpressions,
        uint256 _duration
    ) external payable returns (uint256) {
        require(msg.value >= _budget, "Insufficient funds");
        require(_cpc > 0, "CPC must be greater than 0");
        
        campaignCounter++;
        
        campaigns[campaignCounter] = AdCampaign({
            id: campaignCounter,
            advertiser: msg.sender,
            title: _title,
            budget: _budget,
            spent: 0,
            cpc: _cpc,
            isActive: true,
            startTime: block.timestamp,
            endTime: block.timestamp + _duration,
            maxImpressions: _maxImpressions,
            impressionCount: 0,
            clickCount: 0
        });
        
        emit CampaignCreated(campaignCounter, msg.sender);
        return campaignCounter;
    }
    
    /**
     * @dev 记录广告展示
     * @param _campaignId 广告活动ID
     */
    function recordImpression(uint256 _campaignId) external {
        AdCampaign storage campaign = campaigns[_campaignId];
        
        require(campaign.isActive, "Campaign is not active");
        require(block.timestamp <= campaign.endTime, "Campaign has ended");
        require(campaign.impressionCount < campaign.maxImpressions, "Max impressions reached");
        require(campaign.spent + campaign.cpc <= campaign.budget, "Budget exceeded");
        
        campaign.impressionCount++;
        
        uint256 impressionId = campaign.impressionCount;
        emit AdDisplayed(_campaignId, impressionId);
    }
    
    /**
     * @dev 记录广告点击并处理支付
     * @param _campaignId 广告活动ID
     */
    function recordClick(uint256 _campaignId) external {
        AdCampaign storage campaign = campaigns[_campaignId];
        
        require(campaign.isActive, "Campaign is not active");
        require(block.timestamp <= campaign.endTime, "Campaign has ended");
        require(!hasClicked[_campaignId][msg.sender], "Already clicked this ad");
        require(campaign.spent + campaign.cpc <= campaign.budget, "Budget exceeded");
        
        // 更新统计数据
        campaign.clickCount++;
        campaign.spent += campaign.cpc;
        hasClicked[_campaignId][msg.sender] = true;
        
        // 向点击者支付奖励(90%给点击者,10%作为平台费用)
        uint256 userReward = (campaign.cpc * 90) / 100;
        uint256 platformFee = campaign.cpc - userReward;
        
        payable(msg.sender).transfer(userReward);
        payable(owner).transfer(platformFee);
        
        emit AdClicked(_campaignId, campaign.clickCount, msg.sender);
        emit PaymentProcessed(_campaignId, campaign.cpc);
        
        // 检查预算是否用完
        if (campaign.spent >= campaign.budget) {
            campaign.isActive = false;
        }
    }
    
    /**
     * @dev 获取广告活动详情
     * @param _campaignId 广告活动ID
     */
    function getCampaignDetails(uint256 _campaignId) external view returns (
        uint256 id,
        address advertiser,
        string memory title,
        uint256 budget,
        uint256 spent,
        uint256 cpc,
        bool isActive,
        uint256 impressions,
        uint256 clicks
    ) {
        AdCampaign memory campaign = campaigns[_campaignId];
        return (
            campaign.id,
            campaign.advertiser,
            campaign.title,
            campaign.budget,
            campaign.spent,
            campaign.cpc,
            campaign.isActive,
            campaign.impressionCount,
            campaign.clickCount
        );
    }
}

WordPress插件核心模块

广告活动管理类

<?php
/**
 * 广告活动管理类
 */
class FASC_Ad_Campaign {
    
    private $campaign_id;
    private $blockchain_connector;
    
    public function __construct($campaign_id = null) {
        $this->campaign_id = $campaign_id;
        $this->blockchain_connector = new FASC_Blockchain_Connector();
    }
    
    /**
     * 创建新的广告活动
     */
    public function create_campaign($data) {
        $campaign_data = array(
            'title' => sanitize_text_field($data['title']),
            'budget' => floatval($data['budget']),
            'cpc' => floatval($data['cpc']),
            'max_impressions' => intval($data['max_impressions']),
            'duration_days' => intval($data['duration_days']),
            'ad_content' => wp_kses_post($data['ad_content']),
            'target_url' => esc_url_raw($data['target_url']),
            'status' => 'pending',
            'created_at' => current_time('mysql'),
            'advertiser_id' => get_current_user_id()
        );
        
        // 保存到数据库
        global $wpdb;
        $table_name = $wpdb->prefix . 'fasc_campaigns';
        
        $wpdb->insert($table_name, $campaign_data);
        $local_campaign_id = $wpdb->insert_id;
        
        // 部署到区块链
        $blockchain_data = array(
            'title' => $campaign_data['title'],
            'budget' => $this->convert_to_wei($campaign_data['budget']),
            'cpc' => $this->convert_to_wei($campaign_data['cpc']),
            'maxImpressions' => $campaign_data['max_impressions'],
            'duration' => $campaign_data['duration_days'] * 24 * 60 * 60
        );
        
        $contract_response = $this->blockchain_connector->create_campaign($blockchain_data);
        
        if ($contract_response['success']) {
            // 更新本地记录
            $wpdb->update(
                $table_name,
                array(
                    'contract_address' => $contract_response['contract_address'],
                    'campaign_id' => $contract_response['campaign_id'],
                    'status' => 'active',
                    'transaction_hash' => $contract_response['transaction_hash']
                ),
                array('id' => $local_campaign_id)
            );
            
            return array(
                'success' => true,
                'local_id' => $local_campaign_id,
                'blockchain_id' => $contract_response['campaign_id']
            );
        }
        
        return array('success' => false, 'error' => $contract_response['error']);
    }
    
    /**
     * 显示广告
     */
    public function display_ad() {
        if (!$this->campaign_id) {
            return false;
        }
        
        // 获取广告内容
        $campaign = $this->get_campaign_details();
        
        if (!$campaign || $campaign->status !== 'active') {
            return false;
        }
        
        // 记录展示到区块链
        $this->blockchain_connector->record_impression($campaign->campaign_id);
        
        // 生成广告HTML
        $ad_html = $this->generate_ad_html($campaign);
        
        return $ad_html;
    }
    
    /**
     * 处理广告点击
     */
    public function handle_click() {
        if (!$this->campaign_id) {
            return false;
        }
        
        $campaign = $this->get_campaign_details();
        
        if (!$campaign) {
            return false;
        }
        
        // 调用智能合约记录点击
        $result = $this->blockchain_connector->record_click($campaign->campaign_id);
        
        if ($result['success']) {
            // 记录点击到本地数据库
            $this->log_click($campaign->id);
            
            // 重定向到目标URL
            wp_redirect($campaign->target_url);
            exit;
        }
        
        return $result;
    }
    
    /**
     * 生成广告HTML代码
     */
    private function generate_ad_html($campaign) {
        $click_url = add_query_arg(
            array(
                'fasc_action' => 'click',
                'campaign_id' => $campaign->id,
                'nonce' => wp_create_nonce('fasc_click_' . $campaign->id)
            ),
            home_url('/')
        );
        
        ob_start();
        ?>
        <div class="fasc-ad-container" data-campaign-id="<?php echo esc_attr($campaign->id); ?>">
            <div class="fasc-ad-content">
                <?php echo wp_kses_post($campaign->ad_content); ?>
            </div>
            <a href="<?php echo esc_url($click_url); ?>" 
               class="fasc-ad-link" 
               onclick="fascTrackClick(<?php echo esc_attr($campaign->id); ?>)">
                <span class="fasc-ad-cta">了解更多</span>
            </a>
            <div class="fasc-ad-disclaimer">
                此广告由智能合约驱动,点击可获得奖励
            </div>
        </div>
        <script>
        function fascTrackClick(campaignId) {
            // 发送异步点击统计
            fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: 'action=fasc_track_click&campaign_id=' + campaignId
            });
        }
        </script>
        <?php
        return ob_get_clean();
    }
    
    /**
     * 转换ETH到Wei
     */
    private function convert_to_wei($eth_amount) {
        // 1 ETH = 10^18 Wei
        return bcmul($eth_amount, '1000000000000000000', 0);
    }
    
    /**
     * 获取活动详情
     */
    private function get_campaign_details() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'fasc_campaigns';
        
        return $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $this->campaign_id)
        );
    }
    
    /**
     * 记录点击到本地数据库
     */
    private function log_click($campaign_id) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'fasc_clicks';
        
        $click_data = array(
            'campaign_id' => $campaign_id,
            'user_id' => get_current_user_id(),
            'ip_address' => $_SERVER['REMOTE_ADDR'],
            'user_agent' => $_SERVER['HTTP_USER_AGENT'],
            'clicked_at' => current_time('mysql')
        );
        
        $wpdb->insert($table_name, $click_data);
    }
}
?>

数据库设计

数据表结构

-- 广告活动表
CREATE TABLE `wp_fasc_campaigns` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `title` varchar(255) NOT NULL,
    `advertiser_id` int(11) NOT NULL,
    `budget` decimal(20,8) NOT NULL,
    `cpc` decimal(20,8) NOT NULL,
    `max_impressions` int(11) NOT NULL,
    `duration_days` int(11) NOT NULL,
    `ad_content` text NOT NULL,
    `target_url` varchar(500) NOT NULL,
    `contract_address` varchar(42) DEFAULT NULL,
    `campaign_id` int(11) DEFAULT NULL,
    `transaction_hash` varchar(66) DEFAULT NULL,
    `status` enum('pending','active','paused','completed','cancelled') DEFAULT 'pending',
    `created_at` datetime NOT NULL,
    `updated_at` datetime DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `advertiser_id` (`advertiser_id`),
    KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 广告展示记录表
CREATE TABLE `wp_fasc_impressions` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `campaign_id` int(11) NOT NULL,
    `user_id` int(11) DEFAULT NULL,
    `page_url` varchar(500) NOT NULL,
    `ip_address` varchar(45) DEFAULT NULL,
    `user_agent` text,
    `impressed_at` datetime NOT NULL,
    PRIMARY KEY (`id`),
    KEY `campaign_id` (`campaign_id`),
    KEY `impressed_at` (`impressed_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 广告点击记录表
CREATE TABLE `wp_fasc_clicks` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `campaign_id` int(11) NOT NULL,
    `user_id` int(11) DEFAULT NULL,
    `ip_address` varchar(45) DEFAULT NULL,
    `user_agent` text,
    `clicked_at` datetime NOT NULL,
    `blockchain_tx_hash` varchar(66) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `campaign_id` (`campaign_id`),
    KEY `clicked_at` (`clicked_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 支付记录表
CREATE TABLE `wp_fasc_payments` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `campaign_id` int(11) NOT NULL,
    `user_id` int(11) NOT NULL,
    `amount` decimal(20,8) NOT NULL,
    `transaction_hash` varchar(66) NOT NULL,
    `payment_type` enum('click_reward','refund','withdrawal') NOT NULL,
    `status` enum('pending','completed','failed') DEFAULT 'pending',
    `created_at` datetime NOT NULL,
    `completed_at` datetime DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `campaign_id` (`campaign_id`),
    KEY `user_id` (`user_id`),
    KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

前端集成与用户体验

短代码实现

<?php
/**
 * 广告展示短代码
 */
add_shortcode('flexible_ad', 'fasc_ad_shortcode');

function fasc_ad_shortcode($atts) {
    $atts = shortcode_atts(array(
        'campaign_id' => 0,
        'position' => 'inline',
        'max_width' => '300px'
    ), $atts, 'flexible_ad');
    
    $campaign_id = intval($atts['campaign_id']);
    
    if (!$campaign_id) {
        // 自动选择活动

前端集成与用户体验(续)

短代码实现(续)

<?php
/**
 * 广告展示短代码
 */
add_shortcode('flexible_ad', 'fasc_ad_shortcode');

function fasc_ad_shortcode($atts) {
    $atts = shortcode_atts(array(
        'campaign_id' => 0,
        'position' => 'inline',
        'max_width' => '300px'
    ), $atts, 'flexible_ad');
    
    $campaign_id = intval($atts['campaign_id']);
    
    if (!$campaign_id) {
        // 自动选择活动
        $campaign_id = fasc_get_available_campaign();
    }
    
    if (!$campaign_id) {
        return '<div class="fasc-no-ad">暂无可用广告</div>';
    }
    
    $ad_campaign = new FASC_Ad_Campaign($campaign_id);
    $ad_html = $ad_campaign->display_ad();
    
    // 添加样式
    $style = sprintf(
        'max-width: %s; margin: 20px auto;',
        esc_attr($atts['max_width'])
    );
    
    if ($atts['position'] === 'float_left') {
        $style .= 'float: left; margin-right: 20px;';
    } elseif ($atts['position'] === 'float_right') {
        $style .= 'float: right; margin-left: 20px;';
    }
    
    return sprintf(
        '<div class="fasc-ad-wrapper" style="%s">%s</div>',
        $style,
        $ad_html
    );
}

/**
 * 获取可用广告活动
 */
function fasc_get_available_campaign() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'fasc_campaigns';
    
    // 获取活跃且未超预算的活动
    $campaign = $wpdb->get_row(
        $wpdb->prepare(
            "SELECT id FROM $table_name 
            WHERE status = 'active' 
            AND (max_impressions = 0 OR impression_count < max_impressions)
            AND (end_time IS NULL OR end_time > %s)
            ORDER BY RAND() 
            LIMIT 1",
            current_time('mysql')
        )
    );
    
    return $campaign ? $campaign->id : 0;
}
?>

小工具实现

<?php
/**
 * 广告小工具类
 */
class FASC_Ad_Widget extends WP_Widget {
    
    public function __construct() {
        parent::__construct(
            'fasc_ad_widget',
            __('柔性广告', 'fasc'),
            array('description' => __('显示智能合约驱动的广告', 'fasc'))
        );
    }
    
    public function widget($args, $instance) {
        echo $args['before_widget'];
        
        if (!empty($instance['title'])) {
            echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
        }
        
        $campaign_id = !empty($instance['campaign_id']) ? $instance['campaign_id'] : 0;
        $ad_campaign = new FASC_Ad_Campaign($campaign_id);
        
        echo $ad_campaign->display_ad();
        echo $args['after_widget'];
    }
    
    public function form($instance) {
        $title = !empty($instance['title']) ? $instance['title'] : __('推荐广告', 'fasc');
        $campaign_id = !empty($instance['campaign_id']) ? $instance['campaign_id'] : 0;
        
        // 获取所有活跃广告活动
        global $wpdb;
        $table_name = $wpdb->prefix . 'fasc_campaigns';
        $campaigns = $wpdb->get_results(
            "SELECT id, title FROM $table_name WHERE status = 'active' ORDER BY created_at DESC"
        );
        ?>
        <p>
            <label for="<?php echo esc_attr($this->get_field_id('title')); ?>">
                <?php _e('标题:', 'fasc'); ?>
            </label>
            <input class="widefat" 
                   id="<?php echo esc_attr($this->get_field_id('title')); ?>"
                   name="<?php echo esc_attr($this->get_field_name('title')); ?>"
                   type="text" 
                   value="<?php echo esc_attr($title); ?>">
        </p>
        <p>
            <label for="<?php echo esc_attr($this->get_field_id('campaign_id')); ?>">
                <?php _e('选择广告活动:', 'fasc'); ?>
            </label>
            <select class="widefat"
                    id="<?php echo esc_attr($this->get_field_id('campaign_id')); ?>"
                    name="<?php echo esc_attr($this->get_field_name('campaign_id')); ?>">
                <option value="0"><?php _e('自动选择', 'fasc'); ?></option>
                <?php foreach ($campaigns as $campaign): ?>
                    <option value="<?php echo esc_attr($campaign->id); ?>" 
                            <?php selected($campaign_id, $campaign->id); ?>>
                        <?php echo esc_html($campaign->title); ?>
                    </option>
                <?php endforeach; ?>
            </select>
        </p>
        <?php
    }
    
    public function update($new_instance, $old_instance) {
        $instance = array();
        $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
        $instance['campaign_id'] = (!empty($new_instance['campaign_id'])) ? intval($new_instance['campaign_id']) : 0;
        return $instance;
    }
}

// 注册小工具
add_action('widgets_init', function() {
    register_widget('FASC_Ad_Widget');
});
?>

区块链连接器

Web3集成类

<?php
/**
 * 区块链连接器类
 */
class FASC_Blockchain_Connector {
    
    private $web3;
    private $contract_address;
    private $contract_abi;
    private $account_address;
    private $private_key;
    
    public function __construct() {
        // 从设置中获取配置
        $this->contract_address = get_option('fasc_contract_address');
        $this->account_address = get_option('fasc_account_address');
        $this->private_key = get_option('fasc_private_key');
        
        // 初始化Web3连接
        $this->init_web3();
        
        // 加载合约ABI
        $this->load_contract_abi();
    }
    
    private function init_web3() {
        // 使用Web3.php库
        $provider_url = get_option('fasc_provider_url', 'https://mainnet.infura.io/v3/YOUR_INFURA_KEY');
        
        try {
            $this->web3 = new Web3Web3(new Web3ProvidersHttpProvider(new Web3RequestManagersHttpRequestManager($provider_url, 30)));
        } catch (Exception $e) {
            error_log('Web3初始化失败: ' . $e->getMessage());
        }
    }
    
    private function load_contract_abi() {
        // 从文件加载合约ABI
        $abi_file = FASC_PLUGIN_DIR . 'contracts/FlexibleAdContract.json';
        
        if (file_exists($abi_file)) {
            $abi_content = file_get_contents($abi_file);
            $abi_data = json_decode($abi_content, true);
            $this->contract_abi = $abi_data['abi'];
        }
    }
    
    /**
     * 创建广告活动
     */
    public function create_campaign($data) {
        try {
            // 构建合约调用
            $contract = new Web3Contract($this->web3->provider, $this->contract_abi);
            
            // 估算Gas费用
            $gas_estimate = $this->estimate_gas('createCampaign', [
                $data['title'],
                $data['budget'],
                $data['cpc'],
                $data['maxImpressions'],
                $data['duration']
            ]);
            
            // 构建交易
            $transaction = [
                'from' => $this->account_address,
                'to' => $this->contract_address,
                'value' => '0x' . dechex($data['budget']),
                'gas' => '0x' . dechex($gas_estimate * 2), // 2倍估算值作为安全边际
                'gasPrice' => $this->get_gas_price(),
                'data' => $contract->getData('createCampaign', 
                    $data['title'],
                    $data['budget'],
                    $data['cpc'],
                    $data['maxImpressions'],
                    $data['duration']
                )
            ];
            
            // 签名并发送交易
            $signed_tx = $this->sign_transaction($transaction);
            $tx_hash = $this->send_raw_transaction($signed_tx);
            
            // 等待交易确认
            $receipt = $this->wait_for_transaction_receipt($tx_hash);
            
            if ($receipt && $receipt['status'] === '0x1') {
                // 从事件日志中提取活动ID
                $campaign_id = $this->extract_campaign_id_from_logs($receipt['logs']);
                
                return [
                    'success' => true,
                    'transaction_hash' => $tx_hash,
                    'campaign_id' => $campaign_id,
                    'contract_address' => $this->contract_address
                ];
            }
            
            return ['success' => false, 'error' => '交易失败'];
            
        } catch (Exception $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
    
    /**
     * 记录广告展示
     */
    public function record_impression($campaign_id) {
        try {
            $contract = new Web3Contract($this->web3->provider, $this->contract_abi);
            
            // 调用合约方法(不发送交易,只调用视图函数)
            $contract->at($this->contract_address)->call('recordImpression', $campaign_id, [
                'from' => $this->account_address
            ]);
            
            return ['success' => true];
            
        } catch (Exception $e) {
            error_log('记录展示失败: ' . $e->getMessage());
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
    
    /**
     * 记录广告点击
     */
    public function record_click($campaign_id) {
        try {
            $contract = new Web3Contract($this->web3->provider, $this->contract_abi);
            
            $gas_estimate = $this->estimate_gas('recordClick', [$campaign_id]);
            
            $transaction = [
                'from' => $this->account_address,
                'to' => $this->contract_address,
                'value' => '0x0',
                'gas' => '0x' . dechex($gas_estimate * 2),
                'gasPrice' => $this->get_gas_price(),
                'data' => $contract->getData('recordClick', $campaign_id)
            ];
            
            $signed_tx = $this->sign_transaction($transaction);
            $tx_hash = $this->send_raw_transaction($signed_tx);
            
            $receipt = $this->wait_for_transaction_receipt($tx_hash);
            
            if ($receipt && $receipt['status'] === '0x1') {
                return [
                    'success' => true,
                    'transaction_hash' => $tx_hash
                ];
            }
            
            return ['success' => false, 'error' => '点击记录失败'];
            
        } catch (Exception $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
    
    /**
     * 获取广告活动详情
     */
    public function get_campaign_details($campaign_id) {
        try {
            $contract = new Web3Contract($this->web3->provider, $this->contract_abi);
            
            $details = $contract->at($this->contract_address)->call('getCampaignDetails', $campaign_id, [
                'from' => $this->account_address
            ]);
            
            return [
                'success' => true,
                'data' => $details
            ];
            
        } catch (Exception $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
    
    /**
     * 估算Gas费用
     */
    private function estimate_gas($method, $params) {
        $contract = new Web3Contract($this->web3->provider, $this->contract_abi);
        
        $data = $contract->getData($method, ...$params);
        
        $gas = 0;
        $this->web3->eth->estimateGas([
            'from' => $this->account_address,
            'to' => $this->contract_address,
            'data' => $data
        ], function ($err, $result) use (&$gas) {
            if ($err !== null) {
                throw new Exception($err->getMessage());
            }
            $gas = hexdec($result->toString());
        });
        
        return $gas;
    }
    
    /**
     * 获取当前Gas价格
     */
    private function get_gas_price() {
        $gas_price = '0x0';
        $this->web3->eth->gasPrice(function ($err, $result) use (&$gas_price) {
            if ($err === null) {
                $gas_price = $result->toString();
            }
        });
        return $gas_price;
    }
    
    /**
     * 签名交易
     */
    private function sign_transaction($transaction) {
        // 使用以太坊PHP库进行签名
        // 注意:实际生产环境中应使用更安全的方式管理私钥
        $signed = '';
        
        // 这里简化处理,实际应使用web3.php或ethereum-php的签名功能
        // 或者使用MetaMask等浏览器扩展
        
        return $signed;
    }
    
    /**
     * 发送原始交易
     */
    private function send_raw_transaction($signed_tx) {
        $tx_hash = '';
        $this->web3->eth->sendRawTransaction($signed_tx, function ($err, $result) use (&$tx_hash) {
            if ($err === null) {
                $tx_hash = $result;
            }
        });
        return $tx_hash;
    }
    
    /**
     * 等待交易确认
     */
    private function wait_for_transaction_receipt($tx_hash, $timeout = 60) {
        $start_time = time();
        
        while (time() - $start_time < $timeout) {
            $receipt = null;
            $this->web3->eth->getTransactionReceipt($tx_hash, function ($err, $result) use (&$receipt) {
                if ($err === null && $result !== null) {
                    $receipt = $result;
                }
            });
            
            if ($receipt !== null) {
                return $receipt;
            }
            
            sleep(3); // 等待3秒再检查
        }
        
        return null;
    }
    
    /**
     * 从事件日志中提取活动ID
     */
    private function extract_campaign_id_from_logs($logs) {
        if (!empty($logs) && is_array($logs)) {
            foreach ($logs as $log) {
                if (isset($log['topics'][0]) && 
                    $log['topics'][0] === '0x' . bin2hex('CampaignCreated(uint256,address)')) {
                    // 解码事件数据
                    $campaign_id_hex = substr($log['data'], 2, 64);
                    return hexdec($campaign_id_hex);
                }
            }
        }
        return 0;
    }
}
?>

管理界面

广告活动管理页面

<?php
/**
 * 广告活动管理页面
 */
class FASC_Admin_Pages {
    
    public function __construct() {
        add_action('admin_menu', array($this, 'add_admin_menus'));
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
    }
    
    public function add_admin_menus() {
        // 主菜单
        add_menu_page(
            __('柔性广告智能合约', 'fasc'),
            __('柔性广告', 'fasc'),
            'manage_options',
            'fasc-dashboard',
            array($this, 'render_dashboard_page'),
            'dashicons-money-alt',
            30
        );
        
        // 子菜单
        add_submenu_page(
            'fasc-dashboard',
            __('广告活动', 'fasc'),
            __('广告活动', 'fasc'),
            'manage_options',
            'fasc-campaigns',
            array($this, 'render_campaigns_page')
        );
        
        add_submenu_page(
            'fasc-dashboard',
            __('创建广告', 'fasc'),
            __('创建广告', 'fasc'),
            'manage_options',
            'fasc-create-campaign',
            array($this, 'render_create_campaign_page')
        );
        
        add_submenu_page(
            'fasc-dashboard',
            __('统计数据', 'fasc'),
            __('统计数据', 'fasc'),
            'manage_options',
            'fasc-statistics',
            array($this, 'render_statistics_page')
        );
        
        add_submenu_page(
            'fasc-dashboard',
            __('设置', 'fasc'),
            __('设置', 'fasc'),
            'manage_options',
            'fasc-settings',
            array($this, 'render_settings_page')
        );
    }
    
    public function render_dashboard_page() {
        ?>
        <div class="wrap fasc-admin">
            <h1><?php _e('柔性广告智能合约仪表板', 'fasc'); ?></h1>
            
            <div class="fasc-dashboard-widgets">
                <div class="fasc-widget">
                    <h3><?php _e('今日数据', 'fasc'); ?></h3>
                    <div class="fasc-stats">
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/6323.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部