Polygon招聘高级Golang区块链开发工程师

Polygon招聘高级Golang区块链开发工程师 Polygon Hermez 是一家由超过 35 名专业人士组成的区块链初创公司。团队遍布全球,我们在瑞士和西班牙设有办事处。Polygon Hermez 是 Polygon 生态系统中引以为傲的一员,您可以在此处阅读更多信息

我们的目标是赋予社区和个人自我组织的自由。每个人都应有权做自己并保护自己的隐私。我们旨在通过使用 ZK 证明技术来提高以太坊区块链的可扩展性,创建一个包容且易于访问的区块链支付网络。

我们的协议 Polygon Hermez 是一个去中心化的零知识汇总,旨在扩展以太坊网络并降低交易成本。我们在实现这一目标的同时,也致力于提升用户体验并回馈区块链社区。更多信息可在此处找到:https://hermez.io/

我们提供远程和灵活的工作方式。您将受到一个友好且国际化的团队的热烈欢迎,他们将在您的个人和职业成长过程中提供支持。这是一个积极参与区块链领域并为未来的去中心化做出贡献的激动人心的机会。

我们正在寻找一名 Go 开发人员加入我们的后端团队,帮助开发将运行 EVM zkRollup 的节点。您的任务范围将包括实现默克尔树、以太坊接口(读取/写入智能合约)、EVM 逻辑,以及更“传统”的后端功能,如 API、数据库等。此外,您将与团队成员合作,参与架构决策、选择最佳实践并提出新想法。

这是一个积极参与区块链领域并为未来的去中心化做出贡献的激动人心的机会。

您将做什么?

  • 设计和实现与区块链连接的高质量后端架构。
  • 在紧迫的期限内开发高质量、高性能、现代、简洁且可读的代码。
  • 负责项目从构思到部署的开发和维护工作。
  • 与工程、设计、协议和产品团队协作,贡献想法,为我们的产品路线图和公司目标增加价值。

我们正在寻找具备以下技能和知识的人:

  • 至少 7 年设计和实现高质量后端架构的经验。
  • 至少 3 年使用 Golang 的经验。
  • 理解区块链系统,特别是以太坊。
  • 对公钥/私钥、哈希函数和默克尔树等密码学原语有基本了解(了解如何使用,而非实现)。
  • 有使用 git 的经验。

如果您还具备以下条件,那将非常棒:

  • 对加密货币和 web3 充满热情
  • 熟悉 Docker
  • 熟悉 CI/CD 流水线,特别是 GitHub Actions
  • 熟悉 AWS
  • 了解 L2 区块链解决方案和零知识概念

欢迎随时将您的简历发送至:criscapdevila@polygon.technology;我将非常高兴收到您的来信!


更多关于Polygon招聘高级Golang区块链开发工程师的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

你好, 希望你一切顺利! 已向你发送电子邮件。请查收。 期待尽快收到你的回复。 此致, Jennifer

更多关于Polygon招聘高级Golang区块链开发工程师的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


作为Go语言和区块链领域的开发者,Polygon Hermez的这个职位确实很有吸引力。以下是我从技术角度对职位要求的分析,并附上一些相关的Go代码示例,供感兴趣的开发者参考:

技术要点分析

  1. EVM zkRollup节点开发:这需要深入理解以太坊虚拟机的工作原理和零知识证明的集成方式。

  2. 默克尔树实现:在Go中实现高效的默克尔树是区块链开发的核心技能。

  3. 以太坊接口集成:需要熟练使用Go的以太坊客户端库。

代码示例

1. 默克尔树的基本实现

package main

import (
    "crypto/sha256"
    "encoding/hex"
    "fmt"
)

type MerkleTree struct {
    Root *Node
}

type Node struct {
    Left  *Node
    Right *Node
    Hash  string
}

func NewMerkleTree(data [][]byte) *MerkleTree {
    var nodes []Node
    
    // 创建叶子节点
    for _, d := range data {
        hash := sha256.Sum256(d)
        nodes = append(nodes, Node{
            Hash: hex.EncodeToString(hash[:]),
        })
    }
    
    // 构建默克尔树
    for len(nodes) > 1 {
        var newLevel []Node
        
        for i := 0; i < len(nodes); i += 2 {
            if i+1 < len(nodes) {
                combined := nodes[i].Hash + nodes[i+1].Hash
                hash := sha256.Sum256([]byte(combined))
                newLevel = append(newLevel, Node{
                    Left:  &nodes[i],
                    Right: &nodes[i+1],
                    Hash:  hex.EncodeToString(hash[:]),
                })
            } else {
                newLevel = append(newLevel, nodes[i])
            }
        }
        nodes = newLevel
    }
    
    return &MerkleTree{Root: &nodes[0]}
}

func (mt *MerkleTree) Verify(data []byte) bool {
    leafHash := sha256.Sum256(data)
    leafHashStr := hex.EncodeToString(leafHash[:])
    return mt.verifyNode(mt.Root, leafHashStr)
}

func (mt *MerkleTree) verifyNode(node *Node, targetHash string) bool {
    if node.Left == nil && node.Right == nil {
        return node.Hash == targetHash
    }
    // 递归验证逻辑
    return false
}

2. 以太坊智能合约交互示例

package main

import (
    "context"
    "fmt"
    "log"
    "math/big"

    "github.com/ethereum/go-ethereum"
    "github.com/ethereum/go-ethereum/accounts/abi"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/ethclient"
)

type ContractCaller struct {
    client *ethclient.Client
    abi    abi.ABI
}

func NewContractCaller(rpcURL string, contractABI string) (*ContractCaller, error) {
    client, err := ethclient.Dial(rpcURL)
    if err != nil {
        return nil, err
    }

    parsedABI, err := abi.JSON(strings.NewReader(contractABI))
    if err != nil {
        return nil, err
    }

    return &ContractCaller{
        client: client,
        abi:    parsedABI,
    }, nil
}

func (cc *ContractCaller) CallContract(
    ctx context.Context,
    contractAddress common.Address,
    method string,
    args ...interface{},
) ([]interface{}, error) {
    
    data, err := cc.abi.Pack(method, args...)
    if err != nil {
        return nil, err
    }

    msg := ethereum.CallMsg{
        To:   &contractAddress,
        Data: data,
    }

    result, err := cc.client.CallContract(ctx, msg, nil)
    if err != nil {
        return nil, err
    }

    return cc.abi.Unpack(method, result)
}

func (cc *ContractCaller) GetBalance(ctx context.Context, address common.Address) (*big.Int, error) {
    return cc.client.BalanceAt(ctx, address, nil)
}

3. 高性能API服务器示例

package main

import (
    "encoding/json"
    "log"
    "net/http"
    "sync"
    "time"

    "github.com/gorilla/mux"
)

type BlockData struct {
    BlockNumber uint64    `json:"block_number"`
    Timestamp   time.Time `json:"timestamp"`
    Hash        string    `json:"hash"`
    TxCount     int       `json:"tx_count"`
}

type APIServer struct {
    router *mux.Router
    cache  sync.Map
}

func NewAPIServer() *APIServer {
    r := mux.NewRouter()
    server := &APIServer{router: r}
    
    r.HandleFunc("/block/{number}", server.getBlock).Methods("GET")
    r.HandleFunc("/blocks", server.getRecentBlocks).Methods("GET")
    r.HandleFunc("/health", server.healthCheck).Methods("GET")
    
    return server
}

func (s *APIServer) getBlock(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    blockNumber := vars["number"]
    
    // 检查缓存
    if cached, ok := s.cache.Load(blockNumber); ok {
        json.NewEncoder(w).Encode(cached)
        return
    }
    
    // 模拟从数据库获取数据
    block := &BlockData{
        BlockNumber: 123456,
        Timestamp:   time.Now(),
        Hash:        "0xabc123...",
        TxCount:     42,
    }
    
    // 缓存结果
    s.cache.Store(blockNumber, block)
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(block)
}

func (s *APIServer) getRecentBlocks(w http.ResponseWriter, r *http.Request) {
    blocks := []BlockData{
        {
            BlockNumber: 123456,
            Timestamp:   time.Now(),
            Hash:        "0xabc123...",
            TxCount:     42,
        },
        {
            BlockNumber: 123455,
            Timestamp:   time.Now().Add(-12 * time.Second),
            Hash:        "0xdef456...",
            TxCount:     31,
        },
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(blocks)
}

func (s *APIServer) healthCheck(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Write([]byte(`{"status": "healthy"}`))
}

func (s *APIServer) Start(addr string) error {
    log.Printf("Starting server on %s", addr)
    return http.ListenAndServe(addr, s.router)
}

4. 数据库操作示例(使用PostgreSQL)

package main

import (
    "context"
    "database/sql"
    "fmt"
    "log"
    "time"

    _ "github.com/lib/pq"
)

type TransactionStore struct {
    db *sql.DB
}

func NewTransactionStore(connStr string) (*TransactionStore, error) {
    db, err := sql.Open("postgres", connStr)
    if err != nil {
        return nil, err
    }
    
    if err := db.Ping(); err != nil {
        return nil, err
    }
    
    return &TransactionStore{db: db}, nil
}

func (ts *TransactionStore) SaveTransaction(ctx context.Context, tx *Transaction) error {
    query := `
        INSERT INTO transactions 
        (hash, from_address, to_address, value, block_number, timestamp) 
        VALUES ($1, $2, $3, $4, $5, $6)
        ON CONFLICT (hash) DO NOTHING
    `
    
    _, err := ts.db.ExecContext(ctx, query,
        tx.Hash,
        tx.From,
        tx.To,
        tx.Value,
        tx.BlockNumber,
        tx.Timestamp,
    )
    
    return err
}

func (ts *TransactionStore) GetTransactionsByAddress(
    ctx context.Context, 
    address string, 
    limit, offset int,
) ([]Transaction, error) {
    
    query := `
        SELECT hash, from_address, to_address, value, block_number, timestamp
        FROM transactions 
        WHERE from_address = $1 OR to_address = $1
        ORDER BY block_number DESC
        LIMIT $2 OFFSET $3
    `
    
    rows, err := ts.db.QueryContext(ctx, query, address, limit, offset)
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    
    var transactions []Transaction
    for rows.Next() {
        var tx Transaction
        err := rows.Scan(
            &tx.Hash,
            &tx.From,
            &tx.To,
            &tx.Value,
            &tx.BlockNumber,
            &tx.Timestamp,
        )
        if err != nil {
            return nil, err
        }
        transactions = append(transactions, tx)
    }
    
    return transactions, nil
}

type Transaction struct {
    Hash        string
    From        string
    To          string
    Value       string
    BlockNumber uint64
    Timestamp   time.Time
}

技术要求匹配建议

对于想要申请这个职位的开发者,我建议重点关注以下技术栈的实践经验:

  1. Go语言高级特性:goroutine、channel、context、反射、接口设计
  2. 区块链相关库:go-ethereum、tendermint、libp2p
  3. 密码学库:crypto包、零知识证明相关库
  4. 数据库:PostgreSQL、Redis、LevelDB(用于区块链状态存储)
  5. 容器化:Docker、Kubernetes
  6. 监控和测试:Prometheus、Grafana、单元测试和集成测试

这个职位对Go开发者的要求很高,需要同时具备区块链底层开发经验和传统后端开发能力。对于有7年以上经验的开发者来说,这是一个很好的机会参与前沿的区块链技术开发。

回到顶部